diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index ed86a7c4..2dcd6c77 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -122,6 +122,33 @@ namespace { } + class NonReducedItem { + public: + inline NonReducedItem ( AutoSegment* segment=NULL, uint32_t nonReduceds=0 ); + inline AutoSegment* segment () const; + inline uint32_t nonReduceds () const; + private: + AutoSegment* _segment; + uint32_t _nonReduceds; + }; + + + inline NonReducedItem::NonReducedItem ( AutoSegment* segment, uint32_t nonReduceds ) + : _segment (segment) + , _nonReduceds(nonReduceds) + { } + + inline AutoSegment* NonReducedItem::segment () const { return _segment; } + inline uint32_t NonReducedItem::nonReduceds () const { return _nonReduceds; } + + bool operator< ( const NonReducedItem& lhs, const NonReducedItem& rhs ) + { + int32_t deltaReduceds = (int32_t)lhs.nonReduceds() - (int32_t)rhs.nonReduceds(); + if (deltaReduceds > 0) return true; // Most connected first. + if (deltaReduceds < 0) return false; + return lhs.segment()->getId() < rhs.segment()->getId(); // Smallest Id first. + } + } // Anonymous namespace. @@ -426,14 +453,31 @@ namespace Anabatic { if (_state == EngineDriving) { cdebug_log(145,1) << "Saving AutoContacts/AutoSegments." << endl; + vector reduceds; size_t fixedSegments = 0; size_t sameLayerDoglegs = 0; size_t bloatedStraps = 0; for ( auto isegment : _autoSegmentLut ) { if (isegment.second->isFixed()) ++fixedSegments; - if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs; + if (isegment.second->canReduce( Flags::NullLength )) { + //cerr << "push_back() " << (void*)isegment.second << ":" << isegment.second << endl; + reduceds.push_back( NonReducedItem( isegment.second + , isegment.second->getNonReduceds( Flags::NoFlags ) )); + } else { + if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs; + } //if (isegment.second->bloatStackedStrap()) ++bloatedStraps; } + sort( reduceds.begin(), reduceds.end() ); + // for ( size_t i=0 ; ireduce( Flags::NoFlags ); + if (item.segment()->reduceDoglegLayer()) ++sameLayerDoglegs; + } cmess1 << " o Driving Hurricane data-base." << endl; cmess1 << Dots::asSizet(" - Active AutoSegments" ,AutoSegment::getAllocateds()-fixedSegments) << endl; diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 3a27c455..c5836a1a 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -425,6 +425,16 @@ namespace Anabatic { } + bool AutoSegment::CompareByReduceds::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const + { + uint32_t deltaReduceds = lhs->getReduceds() - rhs->getReduceds(); + if (deltaReduceds < 0) return true; // Smallest source first. + if (deltaReduceds > 0) return false; + + return lhs->getId() < rhs->getId(); // Smallest Id first. + } + + // ------------------------------------------------------------------- // Class : "Anabatic::AutoSegment". @@ -1735,7 +1745,7 @@ namespace Anabatic { } - bool AutoSegment::canReduce () const + bool AutoSegment::canReduce ( Flags flags ) const { cdebug_log(159,0) << "AutoSegment::canReduce():" << this << endl; cdebug_log(159,0) << " _reduceds:" << _reduceds << endl; @@ -1743,7 +1753,8 @@ namespace Anabatic { if (isGlobal() or isDrag() or isFixed()) return false; if (not isSpinTopOrBottom()) return false; if ((getDepth() == 1) and isSpinBottom()) return false; - if (_reduceds) return false; + if ((flags & Flags::WithPerpands) and _reduceds) return false; + if ((flags & Flags::NullLength) and (getAnchoredLength() > 0)) return false; AutoContact* source = getAutoSource(); AutoContact* target = getAutoTarget(); @@ -1773,10 +1784,10 @@ namespace Anabatic { } - bool AutoSegment::reduce () + bool AutoSegment::reduce ( Flags flags ) { if (isReduced()) return false; - if (not canReduce()) return false; + if (not canReduce(flags)) return false; cdebug_log(159,0) << "AutoSegment::reduce():" << this << endl; AutoContact* source = getAutoSource(); @@ -1796,6 +1807,28 @@ namespace Anabatic { } + uint32_t AutoSegment::getNonReduceds ( Flags flags ) const + { + if (not canReduce(flags)) return false; + cdebug_log(159,0) << "AutoSegment::getNonReduceds():" << this << endl; + + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); + uint32_t nonReduceds = 0; + + for ( AutoSegment* perpandicular : source->getAutoSegments() ) { + if (perpandicular == this) continue; + if (perpandicular->getAnchoredLength()) ++nonReduceds; + } + for ( AutoSegment* perpandicular : target->getAutoSegments() ) { + if (perpandicular == this) continue; + if (perpandicular->getAnchoredLength()) ++nonReduceds; + } + + return nonReduceds; + } + + bool AutoSegment::mustRaise () const { if (not (_flags & SegIsReduced)) return false; @@ -2192,8 +2225,9 @@ namespace Anabatic { DebugSession::open( getNet(), 149, 160 ); cdebug_log(159,1) << "AutoSegment::reduceDoglegLayer(): " << this << endl; - AutoContact* source = getAutoSource(); - AutoContact* target = getAutoTarget(); + bool success = false; + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); unsigned int minSourceDepth = Session::getAllowedDepth(); unsigned int maxSourceDepth = 0; @@ -2204,9 +2238,11 @@ namespace Anabatic { unsigned int anchorDepth = Session::getLayerDepth( source->base()->getAnchor()->getLayer() ); minSourceDepth = std::min( minSourceDepth, anchorDepth ); maxSourceDepth = std::max( maxSourceDepth, anchorDepth ); + cdebug_log(151,0) << " source:" << source << endl; } else { for ( AutoSegment* perpandicular : source->getAutoSegments() ) { if (perpandicular == this) continue; + cdebug_log(151,0) << " connected:" << perpandicular << endl; minSourceDepth = std::min( minSourceDepth, perpandicular->getDepth() ); maxSourceDepth = std::max( maxSourceDepth, perpandicular->getDepth() ); } @@ -2215,9 +2251,11 @@ namespace Anabatic { unsigned int anchorDepth = Session::getLayerDepth( target->base()->getAnchor()->getLayer() ); minTargetDepth = std::min( minTargetDepth, anchorDepth ); maxTargetDepth = std::max( maxTargetDepth, anchorDepth ); + cdebug_log(151,0) << " target:" << target << endl; } else { for ( AutoSegment* perpandicular : target->getAutoSegments() ) { if (perpandicular == this) continue; + cdebug_log(151,0) << " connected:" << perpandicular << endl; minTargetDepth = std::min( minTargetDepth, perpandicular->getDepth() ); maxTargetDepth = std::max( maxTargetDepth, perpandicular->getDepth() ); } @@ -2230,20 +2268,26 @@ namespace Anabatic { and (minTargetDepth == maxTargetDepth) and (minSourceDepth == minTargetDepth) ) { const Layer* layer = Session::getRoutingLayer(minSourceDepth); - DbU::Unit side = Session::getWireWidth (minSourceDepth); + DbU::Unit vside = Session::getWireWidth (minSourceDepth); + DbU::Unit hside = Session::getPWireWidth (minSourceDepth); + if (Session::getDirection(minSourceDepth) & Flags::Vertical) + std::swap( hside, vside ); cdebug_log(159,0) << "Reducing to " << minSourceDepth << " " << layer << endl; source->setLayer( layer ); target->setLayer( layer ); setLayer( layer ); - source->setSizes( side, side ); - target->setSizes( side, side ); + setWidth( hside ); + source->setSizes( hside, vside ); + target->setSizes( hside, vside ); + + success = true; } cdebug_tabw(159,-1); DebugSession::close(); - return true; + return success; // if (not source->isTurn() or not target->isTurn()) return true; diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index d3a72004..5856afd9 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -124,6 +124,7 @@ namespace Anabatic { const BaseFlags Flags::LayerCapOnly = (1L << 36); const BaseFlags Flags::NoMinLength = (1L << 37); const BaseFlags Flags::NoSegExt = (1L << 38); + const BaseFlags Flags::NullLength = (1L << 39); Flags::~Flags () diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index c058dae4..6211c389 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -233,7 +233,7 @@ namespace Anabatic { inline bool isWide () const; inline bool isShortNet () const; virtual bool _canSlacken () const = 0; - bool canReduce () const; + bool canReduce ( Flags flags=Flags::WithPerpands ) const; bool mustRaise () const; Flags canDogleg ( Interval ); virtual bool canMoveULeft ( float reserve=0.0 ) const = 0; @@ -290,6 +290,8 @@ namespace Anabatic { virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max ); inline AutoSegment* getCanonical ( Interval& i ); float getMaxUnderDensity ( Flags flags ); + inline uint32_t getReduceds () const; + uint32_t getNonReduceds ( Flags flags=Flags::WithPerpands ) const; // Modifiers. inline void unsetFlags ( uint64_t ); inline void setFlags ( uint64_t ); @@ -334,7 +336,7 @@ namespace Anabatic { bool moveDown ( Flags flags=Flags::NoFlags ); bool reduceDoglegLayer (); bool bloatStackedStrap (); - bool reduce (); + bool reduce ( Flags flags=Flags::WithPerpands ); bool raise (); bool expandToMinLength ( Interval ); bool unexpandToMinLength (); @@ -435,6 +437,9 @@ namespace Anabatic { struct CompareByRevalidate : public binary_function { bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; }; + struct CompareByReduceds : public binary_function { + bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; + }; public: typedef std::set DepthLengthSet; typedef std::set IdSet; @@ -517,6 +522,7 @@ namespace Anabatic { inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); } inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; } inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; } + inline uint32_t AutoSegment::getReduceds () const { return _reduceds; } inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; } inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); } diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 6a9acdcd..be4b708b 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -105,6 +105,7 @@ namespace Anabatic { static const BaseFlags LayerCapOnly ; static const BaseFlags NoMinLength ; static const BaseFlags NoSegExt ; + static const BaseFlags NullLength ; public: inline Flags ( uint64_t flags = NoFlags ); inline Flags ( const Hurricane::BaseFlags& );