diff --git a/katabatic/src/AutoContact.cpp b/katabatic/src/AutoContact.cpp index 41ab547c..fd12eeef 100644 --- a/katabatic/src/AutoContact.cpp +++ b/katabatic/src/AutoContact.cpp @@ -2384,7 +2384,7 @@ namespace Katabatic { length = segment->getLength(); lengths[depth] += length; if ( abs(length) >= DbU::lambda(50.0) ) - cerr << Error("Supicious length:%.2f of %s." + cerr << Error("Suspicious length:%.2f of %s." ,DbU::getLambda(length),getString(autoSegment).c_str()) << endl; } else { if ( isHorizontal ) { diff --git a/katabatic/src/AutoHorizontal.cpp b/katabatic/src/AutoHorizontal.cpp index 2521f2c3..1d7951a0 100644 --- a/katabatic/src/AutoHorizontal.cpp +++ b/katabatic/src/AutoHorizontal.cpp @@ -759,6 +759,7 @@ namespace Katabatic { , false , false ); + segment1->setDogleg ( true ); ltrace(200) << "New " << (void*)dlContact1->getContact() << ":" << dlContact1->getContact() << "." << endl; ltrace(200) << "New " << (void*)dlContact2->getContact() << ":" << dlContact2->getContact() << "." << endl; diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index c08f85cf..d1f4a254 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -551,10 +551,10 @@ namespace Katabatic { // Empty constraint interval: ignore. if ( constraintMin > constraintMax ) return false; - if ( allowOutsideGCell() ) { + if ( isDogleg() ) { // Ugly: hard-wired value of the track spacing. - constraintMin -= DbU::lambda(5.0) * 8; - constraintMax += DbU::lambda(5.0) * 8; + constraintMin -= DbU::lambda(25.0); + constraintMax += DbU::lambda(25.0); } if ( getAxis() < constraintMin ) { @@ -834,7 +834,9 @@ namespace Katabatic { : _isUnsetAxis (true) , _invalidated (false) , _isHorizontal (isHorizontal) + , _isTopologicEnd (false) , _isTerminal (terminal) + , _isDogleg (false) , _isCollapsed (collapsed) , _isCanonical (false) , _isFixed (false) @@ -1265,6 +1267,42 @@ namespace Katabatic { } + float AutoSegment::getMaxUnderDensity ( unsigned int flags ) + { + ltrace(200) << "AutoSegment::getMaxUnderDensity() " << endl; + + GCell* begin = NULL; + GCell* end = NULL; + + size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()); + + vector gcells; + getGCells ( gcells ); + begin = *gcells.begin (); + end = *gcells.rbegin(); + + float maxDensity = 0.0; + + for ( size_t i=0 ; igetFeedthroughs(depth) ); + } + + if ( flags & Propagate ) { + forEach ( AutoSegment*, isegment, getCollapseds() ) { + isegment->getGCells ( gcells ); + if ( (*gcells.begin ())->getIndex() < begin->getIndex() ) begin = *gcells.begin (); + if ( (*gcells.rbegin())->getIndex() > end ->getIndex() ) end = *gcells.rbegin(); + + for ( size_t i=0 ; igetFeedthroughs(depth) ); + } + } + } + + return maxDensity; + } + + bool AutoSegment::canPivotUp ( float reserve, unsigned int flags ) { ltrace(200) << "AutoSegment::canPivotUp() - " << flags @@ -1445,7 +1483,7 @@ namespace Katabatic { bool AutoSegment::moveUp ( unsigned int flags ) { - if ( not canMoveUp(0.0,flags) ) return false; + //if ( not canMoveUp(0.0,flags) ) return false; changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2, flags&Propagate ); return true; @@ -1454,7 +1492,7 @@ namespace Katabatic { bool AutoSegment::moveDown ( unsigned int flags ) { - if ( not canPivotDown(0.0,flags) ) return false; + //if ( not canPivotDown(0.0,flags) ) return false; changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) - 2, flags&Propagate ); return true; @@ -1672,14 +1710,15 @@ namespace Katabatic { string s = getSegment()->_getString(); s.insert ( 1, "id: " ); s.insert ( 4, getString(_id) ); - s.insert ( s.size()-1, (_isFixed )?" F":" -" ); - s.insert ( s.size()-1, (_strap )? "S": "-" ); - s.insert ( s.size()-1, (_isCanonical)? "C": "-" ); - s.insert ( s.size()-1, (_isCollapsed)? "c": "-" ); - s.insert ( s.size()-1, (_isGlobal) ? "g": "-" ); - s.insert ( s.size()-1, (_isTerminal) ? "t": "-" ); - s.insert ( s.size()-1, (_slackened) ? "S": "-" ); - s.insert ( s.size()-1, (_invalidated)? "i": "-" ); + s.insert ( s.size()-1, (_isFixed )?" F":" -" ); + s.insert ( s.size()-1, (_strap )? "S": "-" ); + s.insert ( s.size()-1, (_isCanonical )? "C": "-" ); + s.insert ( s.size()-1, (_isCollapsed )? "c": "-" ); + s.insert ( s.size()-1, (_isGlobal )? "g": "-" ); + s.insert ( s.size()-1, (_isTopologicEnd)? "e": "-" ); + s.insert ( s.size()-1, (_isTerminal )? "t": "-" ); + s.insert ( s.size()-1, (_slackened )? "S": "-" ); + s.insert ( s.size()-1, (_invalidated )? "i": "-" ); return s; } diff --git a/katabatic/src/AutoVertical.cpp b/katabatic/src/AutoVertical.cpp index 186316ac..327daee7 100644 --- a/katabatic/src/AutoVertical.cpp +++ b/katabatic/src/AutoVertical.cpp @@ -668,6 +668,7 @@ namespace Katabatic { , false , false ); + segment1->setDogleg ( true ); ltrace(200) << "New " << (void*)dlContact1->getContact() << ":" << dlContact1->getContact() << "." << endl; ltrace(200) << "New " << (void*)dlContact2->getContact() << ":" << dlContact2->getContact() << "." << endl; ltrace(200) << "Session::dogLeg() perpand: " << segment1 << endl; diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index eac20cb5..abbecdaa 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -98,8 +98,7 @@ namespace { void merge ( DbU::Unit axis, const Interval& ); private: vector _axiss; - DbU::Unit _min; - DbU::Unit _max; + Interval _span; size_t _capacity; size_t _globals; }; @@ -120,6 +119,9 @@ namespace { void UsedFragments::Axis::merge ( const Interval& chunkMerge ) { + // cerr << " Merge @" << DbU::getValueString(_axis) + // << " " << chunkMerge << endl; + list::iterator imerge = _chunks.end(); list::iterator ichunk = _chunks.begin(); @@ -155,9 +157,15 @@ namespace { list::const_iterator inext = ichunk; ++inext; + if ( inext == iend ) break; + Interval currentFree ( (*ichunk).getVMax(), (*inext).getVMin() ); if ( currentFree.getSize() > maxFree.getSize() ) maxFree = currentFree; + + // cerr << " @" << DbU::getValueString(_axis) + // << " before:" << *ichunk << " after:" << *inext + // << " size:" << DbU::getValueString(currentFree.getSize()) << endl; } return maxFree; @@ -182,8 +190,7 @@ namespace { UsedFragments::UsedFragments () : _axiss () - , _min (DbU::Min) - , _max (DbU::Max) + , _span (false) , _capacity(0) , _globals (0) { } @@ -198,15 +205,18 @@ namespace { } - inline DbU::Unit UsedFragments::getMin () const { return _min; } - inline DbU::Unit UsedFragments::getMax () const { return _max; } - inline void UsedFragments::setSpan ( DbU::Unit min, DbU::Unit max ) { _min=min; _max=max; } + inline DbU::Unit UsedFragments::getMin () const { return _span.getVMin(); } + inline DbU::Unit UsedFragments::getMax () const { return _span.getVMax(); } + inline void UsedFragments::setSpan ( DbU::Unit min, DbU::Unit max ) { _span=Interval(min,max); } inline void UsedFragments::setCapacity ( size_t capacity ) { _capacity=capacity; } inline void UsedFragments::incGlobals ( size_t count ) { _globals+=count; } void UsedFragments::merge ( DbU::Unit axis, const Interval& chunkMerge ) { + Interval restrict = chunkMerge.getIntersection(_span); + if ( restrict.isEmpty() ) return; + vector::iterator iaxis = find_if ( _axiss.begin(), _axiss.end(), AxisMatch(axis) ); Axis* paxis = NULL; @@ -218,14 +228,15 @@ namespace { paxis = *iaxis; } - paxis->merge ( chunkMerge ); + paxis->merge ( restrict ); } Interval UsedFragments::getMaxFree () const { - if ( _capacity > _globals + _axiss.size() ) - return Interval(_min,_max); + //cerr << "capacity:" << _capacity << " _globals:" << _globals << " _axiss:" << _axiss.size() << endl; + if ( _capacity > _globals + _axiss.size() + 1 ) + return _span; Interval maxFree; vector::const_iterator iaxis = _axiss.begin(); @@ -909,8 +920,8 @@ namespace Katabatic { _feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33; localCounts [depth] += 1.0; if ( (*isegment)->isGlobal() ) _globalsCount[depth] += 1.0; - ufragments[depth].merge ( (*isegment)->getAxis(), (*isegment)->getSpanU() ); + ufragments[depth].merge ( (*isegment)->getAxis(), (*isegment)->getSpanU() ); if ( (axis != (*isegment)->getAxis()) or (layer != (*isegment)->getLayer()) ) { //_feedthroughs[depth] += 1; //usedAxis[depth].insert ( axis ); @@ -936,12 +947,34 @@ namespace Katabatic { _feedthroughs [i] += (float)(_blockages[i] / _box.getWidth()); //_fragmentations[i] = (hcapacity - _feedthroughs[i]) / (localCounts[i] + 1.0); _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)_box.getWidth(); + + // if ( ((float)ufragments[i].getMaxFree().getSize() + (float)uLengths2[i]) + // > ( hcapacity * (float)_box.getWidth() ) ) { + // cerr << "INCOHERENCY: " << this << "\n " + // << "on d:" << i + // << " frag:" << DbU::getValueString(ufragments[i].getMaxFree().getSize()) + // << " ulength2:" << DbU::getValueString(uLengths2[i]) + // << " capacity:" << DbU::getValueString(hcapacity * _box.getWidth()) + // << " " << getVectorString(_fragmentations,_depth) << endl; + + // } break; case Constant::Vertical: _densities [i] = ((float)uLengths2[i]) / ( vcapacity * (float)_box.getHeight() ); _feedthroughs [i] += (float)(_blockages[i] / _box.getHeight()); //_fragmentations[i] = (vcapacity - _feedthroughs[i]) / (localCounts[i] + 1.0); _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)_box.getHeight(); + + // if ( ((float)ufragments[i].getMaxFree().getSize() + (float)uLengths2[i]) + // > ( vcapacity * (float)_box.getHeight() ) ) { + // cerr << "INCOHERENCY: " << this << "\n " + // << " on d:" << i + // << " frag:" << DbU::getValueString(ufragments[i].getMaxFree().getSize()) + // << " ulength2:" << DbU::getValueString(uLengths2[i]) + // << " capacity:" << DbU::getValueString(vcapacity * _box.getHeight()) + // << " " << getVectorString(_fragmentations,_depth) << endl; + + // } break; } @@ -955,7 +988,7 @@ namespace Katabatic { for ( size_t i=0 ; i<_depth ; i++ ) { _densities[i] = roundfp ( _densities[i] ); } _cDensity = roundfp (_cDensity ); - ltrace(200) << "updateDensity: " << this << endl; + ltrace(190) << "updateDensity: " << this << endl; checkDensity (); @@ -991,25 +1024,25 @@ namespace Katabatic { << endl; } } - for ( size_t i=3 ; i<_depth ; i+=2 ) { - if ( (_densities[i] < 0.5) and (_densities[i-2] < 0.5) ) continue; + // for ( size_t i=3 ; i<_depth ; i+=2 ) { + // if ( (_densities[i] < 0.5) and (_densities[i-2] < 0.5) ) continue; - float balance = _densities[i] / (_densities[i-2]+0.001 ); - if ( (balance > 3) or (balance < .33) ) { - cerr << Warning("%s @%dx%d unbalanced in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)" - ,_getString().c_str() - ,getColumn() - ,getRow() - ,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str() - ,_densities[1] // M2 - ,_densities[2] // M3 - //,_blockages[2] // M4 - ,_densities[3] // M5 - ,_densities[4] // M6 - ) - << endl; - } - } + // float balance = _densities[i] / (_densities[i-2]+0.001 ); + // if ( (balance > 3) or (balance < .33) ) { + // cerr << Warning("%s @%dx%d unbalanced in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)" + // ,_getString().c_str() + // ,getColumn() + // ,getRow() + // ,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str() + // ,_densities[1] // M2 + // ,_densities[2] // M3 + // //,_blockages[2] // M4 + // ,_densities[3] // M5 + // ,_densities[4] // M6 + // ) + // << endl; + // } + // } } return ( _saturated ) ? 1 : 0 ; diff --git a/katabatic/src/LayerAssign.cpp b/katabatic/src/LayerAssign.cpp index 6dac5e44..515dd91e 100644 --- a/katabatic/src/LayerAssign.cpp +++ b/katabatic/src/LayerAssign.cpp @@ -298,6 +298,8 @@ namespace Katabatic { for ( size_t i=0 ; iisVertical() and (globals[i] != seed) ) continue; + if ( globals[i]->canMoveUp(1.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) { unsigned int depth = Session::getRoutingGauge()->getLayerDepth(globals[i]->getLayer()); globals[i]->changeDepth ( depth+2, true, false ); @@ -319,6 +321,10 @@ namespace Katabatic { //if ( locals[i]->canPivotUp(2.0,AutoSegment::Propagate|AutoSegment::IgnoreContact) ) { if ( locals[i]->canPivotUp(2.0,AutoSegment::Propagate) ) { + //if ( locals[i]->isGlobal() and locals[i]->isTopologicEnd() ) continue; + // if ( (locals[i]->isGlobal()) + // and (locals[i]->getMaxUnderDensity(AutoSegment::Propagate) < 5.0) ) continue; + unsigned int depth = Session::getRoutingGauge()->getLayerDepth(locals[i]->getLayer()); locals[i]->changeDepth ( depth+2, true, false ); diff --git a/katabatic/src/LoadGrByNet.cpp b/katabatic/src/LoadGrByNet.cpp index dd262342..5c6349a7 100644 --- a/katabatic/src/LoadGrByNet.cpp +++ b/katabatic/src/LoadGrByNet.cpp @@ -2,13 +2,13 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved // // =================================================================== // // $Id$ // -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ // | | // | C O R I O L I S | // | K a t a b a t i c - Routing Toolbox | @@ -20,7 +20,7 @@ // | *************************************************************** | // | U p d a t e s | // | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include @@ -1094,13 +1094,14 @@ namespace { public: // Methods. + static void init ( unsigned int degree ); + static void fixSegments (); GCellConfiguration ( GCellGrid* gcellGrid , Hook* fromHook , AutoContact* sourceContact=NULL ); void construct ( ForkStack& forks ); inline unsigned int getStateG () const; inline GCell* getGCell () const; - static void fixSegments (); static bool _GCell_rp_AutoContacts ( GCell* gcell , RoutingPad* rp , AutoContact*& source @@ -1234,6 +1235,8 @@ namespace { // Attributes. private: static vector _toFixSegments; + static bool _onTopologicEnd; + static unsigned int _degree; UState _state; unsigned int _topology; Net* _net; @@ -1255,6 +1258,8 @@ namespace { vector GCellConfiguration::_toFixSegments; + bool GCellConfiguration::_onTopologicEnd = false; + unsigned int GCellConfiguration::_degree = 0; void GCellConfiguration::fixSegments () @@ -1265,6 +1270,14 @@ namespace { } + void GCellConfiguration::init ( unsigned int degree ) + { + _degree = degree; + _onTopologicEnd = false; + _toFixSegments.clear (); + } + + GCellConfiguration::GCellConfiguration ( GCellGrid* gcellGrid , Hook* fromHook , AutoContact* sourceContact ) @@ -1344,6 +1357,7 @@ namespace { if (_state.fields.globals == 1) { if ( _north || _south ) _topology |= GLOBAL_VERTICAL_END; else _topology |= GLOBAL_HORIZONTAL_END; + _onTopologicEnd = true; } else if (_state.fields.globals == 2) { if ( _east && _west ) _topology |= GLOBAL_HORIZONTAL; else if ( _north && _south ) _topology |= GLOBAL_VERTICAL; @@ -1454,6 +1468,10 @@ namespace { , targetContact , static_cast( _fromHook->getComponent() ) ); + globalSegment->setTopologicEnd ( _onTopologicEnd ); + _onTopologicEnd = false; + globalSegment->setBipoint ( (_degree == 2) ); + ltrace(99) << "Create global segment: " << globalSegment << endl; if ( globalSegment->isHorizontal() @@ -2482,8 +2500,9 @@ namespace Katabatic { lookupClear (); - RoutingPads routingPads = net->getRoutingPads (); - if ( routingPads.getSize() < 2 ) { + RoutingPads routingPads = net->getRoutingPads (); + size_t degree = routingPads.getSize(); + if ( degree < 2 ) { #if 0 if ( !getDemoMode() ) cmess2 << Warning("Net \"%s\" have less than 2 plugs/pins (ignored)." @@ -2498,6 +2517,9 @@ namespace Katabatic { GCell* lowestGCell = NULL; size_t unconnecteds = 0; size_t connecteds = 0; + + GCellConfiguration::init ( degree ); + ltrace(99) << "Start RoutingPad Ring" << endl; forEach ( RoutingPad*, startRp, routingPads ) { bool segmentFound = false; diff --git a/katabatic/src/katabatic/AutoSegment.h b/katabatic/src/katabatic/AutoSegment.h index 9d517d1f..1bdb03f7 100644 --- a/katabatic/src/katabatic/AutoSegment.h +++ b/katabatic/src/katabatic/AutoSegment.h @@ -186,11 +186,14 @@ namespace Katabatic { // Predicates. inline bool isHorizontal () const; inline bool isVertical () const; + inline bool isBipoint () const; + inline bool isTopologicEnd () const; inline bool isInvalidated () const; inline bool isGlobal () const; inline bool isLocal () const; inline bool isCanonicalLocal () const; inline bool isTerminal () const; + inline bool isDogleg () const; inline bool isCollapsed () const; inline bool isCanonical () const; inline bool isFixed () const; @@ -211,6 +214,7 @@ namespace Katabatic { bool canSlacken ( bool propagate=false ); virtual bool _canSlacken () const = 0; bool canGoOutsideGCell () const; + float getMaxUnderDensity ( unsigned int flags ); // Accessors. inline unsigned long getId () const; virtual unsigned int getDirection () const = 0; @@ -252,10 +256,13 @@ namespace Katabatic { // Static Modifiers. static void setDestroyMode ( bool ); // Modifiers. + inline void setBipoint ( bool ); + inline void setTopologicEnd ( bool ); inline void setGlobal ( bool ); inline void setCanonicalLocal ( bool ); inline void setCanonical ( bool ); inline void setTerminal ( bool ); + inline void setDogleg ( bool ); inline void setFixed ( bool ); inline void setStrap ( bool ); inline void setLayerChange ( bool ); @@ -329,9 +336,12 @@ namespace Katabatic { bool _isUnsetAxis; bool _invalidated; bool _isHorizontal; + bool _isBipoint; + bool _isTopologicEnd; bool _isGlobal; bool _isCanonicalLocal; bool _isTerminal; + bool _isDogleg; bool _isCollapsed; bool _isCanonical; bool _isFixed; @@ -406,11 +416,14 @@ namespace Katabatic { inline bool AutoSegment::isInvalidated () const { return _invalidated; } inline bool AutoSegment::isHorizontal () const { return _isHorizontal; } + inline bool AutoSegment::isBipoint () const { return _isBipoint; } + inline bool AutoSegment::isTopologicEnd () const { return _isTopologicEnd; } inline bool AutoSegment::isVertical () const { return !_isHorizontal; } inline bool AutoSegment::isGlobal () const { return _isGlobal; } inline bool AutoSegment::isCanonicalLocal () const { return _isCanonicalLocal; } inline bool AutoSegment::isLocal () const { return !_isGlobal; } inline bool AutoSegment::isTerminal () const { return _isTerminal; } + inline bool AutoSegment::isDogleg () const { return _isDogleg ; } inline bool AutoSegment::isCollapsed () const { return _isCollapsed; } inline bool AutoSegment::isCanonical () const { return _isCanonical; } inline bool AutoSegment::isFixed () const { return _isFixed; } @@ -424,9 +437,12 @@ namespace Katabatic { inline void AutoSegment::setLayer ( const Layer* layer ) { invalidate(); getSegment()->setLayer(layer); } inline void AutoSegment::setInvalidated ( bool state ) { _invalidated = state; } + inline void AutoSegment::setBipoint ( bool state ) { _isBipoint = state; } + inline void AutoSegment::setTopologicEnd ( bool state ) { _isTopologicEnd = state; } inline void AutoSegment::setGlobal ( bool state ) { _isGlobal = state; } inline void AutoSegment::setCanonicalLocal ( bool state ) { _isCanonicalLocal = state; } inline void AutoSegment::setTerminal ( bool state ) { _isTerminal = state; } + inline void AutoSegment::setDogleg ( bool state ) { _isDogleg = state; } inline void AutoSegment::setFixed ( bool state ) { _isFixed = state; } inline void AutoSegment::setStrap ( bool state ) { _strap = state; } inline void AutoSegment::setLayerChange ( bool state ) { _layerChange = state; } diff --git a/katabatic/src/katabatic/GCell.h b/katabatic/src/katabatic/GCell.h index 9aec2d84..3c14022d 100644 --- a/katabatic/src/katabatic/GCell.h +++ b/katabatic/src/katabatic/GCell.h @@ -142,6 +142,7 @@ namespace Katabatic { float getDensity ( bool update=true ) const; inline DbU::Unit getBlockage ( unsigned int depth ) const; inline float getFragmentation ( unsigned int depth ) const; + inline float getFeedthroughs ( unsigned int depth ) const; inline float getGlobalsCount ( unsigned int depth ) const; float getStiffness () const; inline vector* getVSegments (); @@ -272,6 +273,9 @@ namespace Katabatic { inline float GCell::getFragmentation ( unsigned int depth ) const { if (_invalid) const_cast(this)->updateDensity(); return _fragmentations[depth]; } + inline float GCell::getFeedthroughs ( unsigned int depth ) const + { if (_invalid) const_cast(this)->updateDensity(); return _feedthroughs[depth]; } + inline float GCell::getGlobalsCount ( unsigned int depth ) const { if (_invalid) const_cast(this)->updateDensity(); return _globalsCount[depth]; }