From 0df293655a07af6788615de86d6946d06dda4fb2 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 9 Jan 2011 18:08:31 +0000 Subject: [PATCH] * ./katabatic: - New: In GCell, compute a "fragmentation" indice, the average free track length, the more fragmented, the smaller the indice. - New: In AutoSegment::canMoveUp(), when requested, not only check for free (parallel) track in the up layer but also check that the begin/end local segments created to maintain layer connexity do not creates too much fragmentation. This fragment could prove critical in higly dense GCells. - Change: In LayerAssign, disable the ::rpDesaturate() steps, after optimization the router can handle 10 terminals per GCells in M2 without problem. And ::rpDesaturate() must uses GCell::stepNetDesaturate() and *not* directly ::stepDesaturate(). --- katabatic/src/AutoContact.cpp | 20 +- katabatic/src/AutoSegment.cpp | 73 ++++- katabatic/src/GCell.cpp | 370 ++++++++++++++++++++-- katabatic/src/LayerAssign.cpp | 41 +-- katabatic/src/katabatic/AutoContact.h | 3 +- katabatic/src/katabatic/AutoSegment.h | 15 +- katabatic/src/katabatic/GCell.h | 39 ++- katabatic/src/katabatic/KatabaticEngine.h | 3 +- 8 files changed, 499 insertions(+), 65 deletions(-) diff --git a/katabatic/src/AutoContact.cpp b/katabatic/src/AutoContact.cpp index b05cfa14..41ab547c 100644 --- a/katabatic/src/AutoContact.cpp +++ b/katabatic/src/AutoContact.cpp @@ -247,6 +247,7 @@ namespace { inline DbU::Unit getDuTarget () const; inline DbU::Unit getAxis () const; inline DbU::Unit getWidth () const; + inline void setSlackened ( bool ); inline void setDuSource ( DbU::Unit ); inline void setDuTarget ( DbU::Unit ); inline void invert (); @@ -313,6 +314,7 @@ namespace { inline DbU::Unit SegmentEnd::getDuTarget () const { return _autoSegment->getDuTarget(); } inline DbU::Unit SegmentEnd::getAxis () const { return _autoSegment->getAxis(); } inline DbU::Unit SegmentEnd::getWidth () const { return _autoSegment->getWidth(); } + inline void SegmentEnd::setSlackened ( bool state ) { _autoSegment->setSlackened(state); } inline void SegmentEnd::setDuSource ( DbU::Unit du ) { _autoSegment->setDuSource(du); } inline void SegmentEnd::setDuTarget ( DbU::Unit du ) { _autoSegment->setDuTarget(du); } inline void SegmentEnd::invert () { _autoSegment->invert(); } @@ -1462,8 +1464,8 @@ namespace { } // The complete case. - bool hExtended = isHExtended(); - bool vExtended = isVExtended(); + //bool hExtended = isHExtended(); + //bool vExtended = isVExtended(); bool xFound = false; bool yFound = false; vector hBottom; @@ -1497,6 +1499,8 @@ namespace { for ( size_t i=0; i < _localEnds.size() ; i++ ) { ltrace(200) << "| L: " << _localEnds[i] << endl; + _localEnds[i]->setSlackened ( true ); + if ( _localEnds[i]->isHorizontal() ) { if ( not yFound ) { yFound = true; @@ -1696,8 +1700,9 @@ namespace { , true // terminal. , false // Temporary: *not* collapsed. ); - segment->setLayer ( _routingGauge->getRoutingLayer(1) ); - segment->setAxis ( position.getY() ); + segment->setLayer ( _routingGauge->getRoutingLayer(1) ); + segment->setAxis ( position.getY() ); + segment->setSlackened ( true ); ltrace(200) << "@" << DbU::getValueString(position.getY()) << segment << endl; segment = AutoSegment::create ( via23 @@ -1707,8 +1712,9 @@ namespace { , false // terminal. , false //true // collapsed. ); - segment->setAxis ( position.getX() ); - segment->setLayer ( _routingGauge->getRoutingLayer(2) ); + segment->setAxis ( position.getX() ); + segment->setLayer ( _routingGauge->getRoutingLayer(2) ); + segment->setSlackened ( true ); _contact->setLayer ( _routingGauge->getContactLayer(1) ); ltrace(200) << "@" << DbU::getValueString(position.getX()) << segment << endl; @@ -2349,7 +2355,7 @@ namespace Katabatic { } - void AutoContact::getLengths ( DbU::Unit* lengths, set& processeds ) + void AutoContact::getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& processeds ) { forEach ( Hook*, ihook, getBodyHook()->getSlaveHooks() ) { bool isSourceHook = (dynamic_cast(*ihook)); diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index 0a00aacc..c08f85cf 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -286,6 +286,29 @@ namespace Katabatic { } +// ------------------------------------------------------------------- +// Class : "Katabatic::AutoSegment::CompareByDepthAxis". + + + bool AutoSegment::CompareByDepthAxis::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const + { + int deltaDepth = (int)(Session::getRoutingGauge()->getLayerDepth(lhs->getLayer())) + - (int)(Session::getRoutingGauge()->getLayerDepth(rhs->getLayer())); + if ( deltaDepth < 0 ) return true; // Lowest layer first. + if ( deltaDepth > 0 ) return false; + + DbU::Unit deltaUnit = lhs->getAxis() - rhs->getAxis(); + if ( deltaUnit < 0 ) return true; // Smallest axis first. + if ( deltaUnit > 0 ) return false; + + deltaUnit = lhs->getSourceU() - rhs->getSourceU(); + if ( deltaUnit < 0 ) return true; // Smallest source first. + if ( deltaUnit > 0 ) return false; + + return lhs->getId() < rhs->getId(); // Smallest Id first. + } + + // ------------------------------------------------------------------- // Class : "Katabatic::AutoSegment". @@ -1244,7 +1267,8 @@ namespace Katabatic { bool AutoSegment::canPivotUp ( float reserve, unsigned int flags ) { - ltrace(200) << "AutoSegment::canPivotUp() - " << flags << endl; + ltrace(200) << "AutoSegment::canPivotUp() - " << flags + << " (reserve:" << reserve << ")" << endl; if ( isLayerChange() or isFixed() ) return false; if ( isTerminal () or isLocal() ) return false; @@ -1293,7 +1317,8 @@ namespace Katabatic { bool AutoSegment::canPivotDown ( bool propagate, float reserve ) { - ltrace(200) << "AutoSegment::canPivotDown()" << endl; + ltrace(200) << "AutoSegment::canPivotDown()" + << " (reserve:" << reserve << ")" << endl; if ( isLayerChange() or isFixed() ) return false; if ( isTerminal () or isLocal() ) return false; @@ -1332,7 +1357,7 @@ namespace Katabatic { } } - ltrace(200) << "AutoSegment::canPivotUp() - true [propagate]" << endl; + ltrace(200) << "AutoSegment::canPivotDown() - true [propagate]" << endl; return true; } @@ -1340,7 +1365,11 @@ namespace Katabatic { bool AutoSegment::canMoveUp ( float reserve, unsigned int flags ) { - ltrace(200) << "AutoSegment::canMoveUp() " << flags << endl; + ltrace(200) << "AutoSegment::canMoveUp() " << flags + << " (reserve:" << reserve << ")" << endl; + + GCell* begin = NULL; + GCell* end = NULL; if ( isLayerChange() or isFixed() ) return false; if ( isTerminal() and (not (flags & AllowTerminal)) ) return false; @@ -1351,6 +1380,9 @@ namespace Katabatic { vector gcells; getGCells ( gcells ); + begin = *gcells.begin (); + end = *gcells.rbegin(); + for ( size_t i=0 ; ihasFreeTrack(depth,reserve) ) { ltrace(200) << "Not enough free track in " << gcells[i] << endl; @@ -1373,6 +1405,9 @@ namespace Katabatic { if ( isegment->isGlobal() ) hasGlobalSegment = true; 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 ; ihasFreeTrack(depth,reserve) ) { ltrace(200) << "Not enough free track in " << gcells[i] << endl; @@ -1382,6 +1417,28 @@ namespace Katabatic { } } + if ( (depth >= 4) and (flags & PerpandicularFrag) ) { + float fragmentation = begin->getFragmentation(depth-1); + ltrace(200) << "Check begin GCell perpandicular fragmentation: " << fragmentation << endl; + + if ( fragmentation < 0.5 ) { + ltrace(200) << "Not enough free track for perpandicular in begin GCell " + << "(frag:" << fragmentation << ")." + << endl; + return false; + } + + fragmentation = end->getFragmentation(depth-1); + ltrace(200) << "Check end GCell perpandicular fragmentation: " << fragmentation << endl; + + if ( fragmentation < 0.5 ) { + ltrace(200) << "Not enough free track for perpandicular in end GCell " + << "(frag:" << fragmentation << ")." + << endl; + return false; + } + } + return true; } @@ -1942,7 +1999,7 @@ namespace Katabatic { stack.push ( seed->getAutoSource(), seed ); stack.push ( seed->getAutoTarget(), seed ); - while ( !stack.isEmpty() ) { + while ( not stack.isEmpty() ) { AutoContact* sourceContact = stack.getAutoContact (); AutoSegment* sourceSegment = stack.getAutoSegment (); @@ -1960,10 +2017,10 @@ namespace Katabatic { forEach ( Component*, component, sourceContact->getSlaveComponents() ) { Segment* segment = dynamic_cast(*component); - if ( ( !segment ) || ( segment == sourceSegment->getSegment() ) ) continue; + if ( ( not segment ) || ( segment == sourceSegment->getSegment() ) ) continue; AutoSegment* currentSegment = Session::lookup ( segment ); - if ( !currentSegment ) { + if ( not currentSegment ) { cerr << Error("Can't lookup for %s.",getString(segment).c_str()) << endl; continue; } @@ -1983,7 +2040,7 @@ namespace Katabatic { continue; } - if ( !areAligneds(currentSegment,seed) ) { + if ( not areAligneds(currentSegment,seed) ) { collapseds.push_back ( currentSegment ); ltrace(79) << "collapsed: " << currentSegment << endl; } diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index 67ef293b..eac20cb5 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -44,6 +44,204 @@ #include "katabatic/KatabaticEngine.h" +namespace { + + using namespace std; + using namespace Hurricane; + using namespace Katabatic; + + +// ------------------------------------------------------------------- +// Class : "::UsedFragments". + + + class UsedFragments { + private: + class Axiss; + + class Axis { + public: + Axis ( UsedFragments*, DbU::Unit axis ); + inline DbU::Unit getAxis () const; + inline UsedFragments* getUsedFragments () const; + void merge ( const Interval& mergeChunk ); + Interval getMaxFree () const; + private: + UsedFragments* _ufragments; + DbU::Unit _axis; + list _chunks; + }; + + private: + class AxisCompare { + public: + bool operator() ( const Axis* lhs, const Axis* rhs ); + }; + + class AxisMatch : public unary_function { + public: + inline AxisMatch ( DbU::Unit axis ); + inline bool operator() ( const Axis* ); + private: + DbU::Unit _axis; + }; + + public: + UsedFragments (); + ~UsedFragments (); + inline DbU::Unit getMin () const; + inline DbU::Unit getMax () const; + Interval getMaxFree () const; + inline void setSpan ( DbU::Unit min, DbU::Unit max ); + inline void setCapacity ( size_t ); + inline void incGlobals ( size_t count=1 ); + void merge ( DbU::Unit axis, const Interval& ); + private: + vector _axiss; + DbU::Unit _min; + DbU::Unit _max; + size_t _capacity; + size_t _globals; + }; + + + UsedFragments::Axis::Axis ( UsedFragments* ufragments, DbU::Unit axis ) + : _ufragments(ufragments) + , _axis (axis) + , _chunks () + { + merge ( Interval ( ufragments->getMin()-DbU::lambda(5.0), ufragments->getMin() ) ); + merge ( Interval ( ufragments->getMax(), ufragments->getMax()+DbU::lambda(5.0) ) ); + } + + inline DbU::Unit UsedFragments::Axis::getAxis () const { return _axis; } + inline UsedFragments* UsedFragments::Axis::getUsedFragments () const { return _ufragments; } + + + void UsedFragments::Axis::merge ( const Interval& chunkMerge ) + { + list::iterator imerge = _chunks.end(); + list::iterator ichunk = _chunks.begin(); + + while ( ichunk != _chunks.end() ) { + if ( chunkMerge.getVMax() < (*ichunk).getVMin() ) break; + + if ( chunkMerge.intersect(*ichunk) ) { + if ( imerge == _chunks.end() ) { + imerge = ichunk; + (*imerge).merge ( chunkMerge ); + } else { + (*imerge).merge ( *ichunk ); + ichunk = _chunks.erase ( ichunk ); + continue; + } + } + ichunk++; + } + + if ( imerge == _chunks.end() ) { + _chunks.insert ( ichunk, chunkMerge ); + } + } + + + Interval UsedFragments::Axis::getMaxFree () const + { + list::const_iterator ichunk = _chunks.begin(); + list::const_iterator iend = --_chunks.end(); + + Interval maxFree; + for ( ; ichunk != iend ; ++ichunk ) { + list::const_iterator inext = ichunk; + ++inext; + + Interval currentFree ( (*ichunk).getVMax(), (*inext).getVMin() ); + if ( currentFree.getSize() > maxFree.getSize() ) + maxFree = currentFree; + } + + return maxFree; + } + + + inline bool UsedFragments::AxisCompare::operator() ( const Axis* lhs, const Axis* rhs ) + { + if ( lhs->getAxis () < rhs->getAxis () ) return true; + return false; + } + + + inline UsedFragments::AxisMatch::AxisMatch ( DbU::Unit axis ) + : _axis(axis) + { } + + + inline bool UsedFragments::AxisMatch::operator() ( const Axis* axis ) + { return (axis->getAxis() == _axis); } + + + UsedFragments::UsedFragments () + : _axiss () + , _min (DbU::Min) + , _max (DbU::Max) + , _capacity(0) + , _globals (0) + { } + + + UsedFragments::~UsedFragments () + { + while ( not _axiss.empty() ) { + delete (*_axiss.begin()); + _axiss.erase ( _axiss.begin() ); + } + } + + + 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 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 ) + { + vector::iterator iaxis = find_if ( _axiss.begin(), _axiss.end(), AxisMatch(axis) ); + + Axis* paxis = NULL; + if ( iaxis == _axiss.end() ) { + paxis = new Axis(this,axis); + _axiss.push_back ( paxis ); + stable_sort ( _axiss.begin(), _axiss.end(), AxisCompare() ); + } else { + paxis = *iaxis; + } + + paxis->merge ( chunkMerge ); + } + + + Interval UsedFragments::getMaxFree () const + { + if ( _capacity > _globals + _axiss.size() ) + return Interval(_min,_max); + + Interval maxFree; + vector::const_iterator iaxis = _axiss.begin(); + for ( ; iaxis != _axiss.end() ; ++iaxis ) { + Interval axisMaxFree = (*iaxis)->getMaxFree(); + if ( axisMaxFree.getSize() > maxFree.getSize() ) + maxFree = axisMaxFree; + } + + return maxFree; + } + + +} // End of anonymous namespace. + + namespace Katabatic { @@ -60,6 +258,39 @@ namespace Katabatic { using Hurricane::Vertical; +// ------------------------------------------------------------------- +// Class : "Katabatic::GCell::BlockedAxis". + + + GCell::BlockedAxis::BlockedAxis ( GCell* gcell ) + : _gcell (gcell) + , _axisSets(new set* [_gcell->getDepth()]) + { + for ( size_t i=0 ; i<_gcell->getDepth() ; ++i ) _axisSets[i] = NULL; + } + + + const set& GCell::BlockedAxis::getAxisSet ( size_t depth ) const + { + static const set _emptySet; + + if ( (depth >= _gcell->getDepth()) or (not _axisSets[depth]) ) + return _emptySet; + + return *(_axisSets[depth]); + } + + + void GCell::BlockedAxis::addAxis ( size_t depth, DbU::Unit axis ) + { + if ( depth >= _gcell->getDepth() ) return; + if ( not _axisSets[depth] ) _axisSets[depth] = new set(); + + _axisSets[depth]->insert ( axis ); + } + + + // ------------------------------------------------------------------- // Class : "Katabatic::GCell::CompareByDensity". @@ -116,7 +347,11 @@ namespace Katabatic { , _blockages (new DbU::Unit [_depth]) , _cDensity (0.0) , _densities (new float [_depth]) - // , _saturateDensities (new float [_depth]) + , _feedthroughs (new float [_depth]) + , _fragmentations (new float [_depth]) + , _globalsCount (new float [_depth]) + //, _blockedAxis (this) + //, _saturateDensities (new float [_depth]) , _saturated (false) , _invalid (true) , _key (0.0,_index) @@ -124,6 +359,9 @@ namespace Katabatic { for ( size_t i=0 ; i<_depth ; i++ ) { _blockages [i] = 0; _densities [i] = 0.0; + _feedthroughs [i] = 0.0; + _fragmentations [i] = 0.0; + _globalsCount [i] = 0.0; //_saturateDensities[i] = 0.0; if ( Session::getRoutingGauge()->getLayerGauge(i)->getType() == Constant::PinOnly ) @@ -167,6 +405,7 @@ namespace Katabatic { delete [] _blockages; delete [] _densities; + delete [] _feedthroughs; //delete [] _saturateDensities; _allocateds--; @@ -433,6 +672,13 @@ namespace Katabatic { } + // void GCell::addBlockedAxis ( unsigned int depth, DbU::Unit axis ) + // { + // _invalid = true; + // _blockedAxis.addAxis ( depth, axis ); + // } + + void GCell::removeContact ( AutoContact* ac ) { size_t begin = 0; @@ -533,7 +779,7 @@ namespace Katabatic { size_t GCell::updateDensity () { - if ( !_invalid ) return (_saturated) ? 1 : 0; + if ( not _invalid ) return (_saturated) ? 1 : 0; _saturated = false; @@ -551,18 +797,39 @@ namespace Katabatic { for ( size_t i=0 ; i<_vsegments.size() ; i++ ) cerr << "Order: " << _vsegments[i] << endl; #endif - float hcapacity = getHCapacity (); - float vcapacity = getVCapacity (); - float ccapacity = hcapacity * vcapacity * 4; - DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/; - DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/; - DbU::Unit uLengths1 [ _depth ]; - DbU::Unit uLengths2 [ _depth ]; + float hcapacity = getHCapacity (); + float vcapacity = getVCapacity (); + float ccapacity = hcapacity * vcapacity * 4; + DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/; + DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/; + DbU::Unit uLengths1 [ _depth ]; + DbU::Unit uLengths2 [ _depth ]; + float localCounts [ _depth ]; + UsedFragments ufragments [ _depth ]; + //set usedAxis [ _depth ]; - for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] = 0; + for ( size_t i=0 ; i<_depth ; i++ ) { + _feedthroughs[i] = 0.0; + uLengths2 [i] = 0; + localCounts [i] = 0.0; + _globalsCount[i] = 0.0; + + switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { + case Constant::Horizontal: + ufragments[i].setSpan ( _box.getXMin(), _box.getXMax() ); + ufragments[i].setCapacity ( (size_t)hcapacity ); + break; + case Constant::Vertical: + ufragments[i].setSpan ( _box.getYMin(), _box.getYMax() ); + ufragments[i].setCapacity ( (size_t)vcapacity ); + break; + } + + //usedAxis [i] = _blockedAxis.getAxisSet ( i ); + } // Compute wirelength associated to contacts (in DbU::Unit converted to float). - set processeds; + AutoSegment::DepthLengthSet processeds; vector::iterator it = _contacts.begin(); vector::iterator end = _contacts.end (); for ( ; it != end ; it++ ) { @@ -582,6 +849,9 @@ namespace Katabatic { size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t count = 0; for ( size_t i=0 ; i<_hsegments.size() ; i++ ) { + _globalsCount[depth] += 1.0; + ufragments [depth].incGlobals(); + if ( layer != _hsegments[i]->getLayer() ) { uLengths2[depth] += count * _box.getWidth(); @@ -590,6 +860,8 @@ namespace Katabatic { depth = Session::getRoutingGauge()->getLayerDepth(layer); } count++; + _feedthroughs[depth] += 1.0; + //usedAxis[depth].insert ( _hsegments[i]->getAxis() ); } if ( count ) { uLengths2[depth] += count * _box.getWidth(); @@ -602,6 +874,9 @@ namespace Katabatic { size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t count = 0; for ( size_t i=0 ; i<_vsegments.size() ; i++ ) { + _globalsCount[depth] += 1.0; + ufragments [depth].incGlobals(); + if ( layer != _vsegments[i]->getLayer() ) { uLengths2[depth] += count * _box.getHeight(); @@ -610,6 +885,8 @@ namespace Katabatic { depth = Session::getRoutingGauge()->getLayerDepth(layer); } count++; + _feedthroughs[depth] += 1.0; + //usedAxis[depth].insert ( _vsegments[i]->getAxis() ); } if ( count ) { uLengths2[depth] += count * _box.getHeight(); @@ -621,25 +898,61 @@ namespace Katabatic { uLengths2[i] += _blockages[i]; } + // Compute the number of non pass-through tracks. + if ( processeds.size() ) { + AutoSegment::DepthLengthSet::iterator isegment = processeds.begin(); + const Layer* layer = (*isegment)->getLayer(); + DbU::Unit axis = (*isegment)->getAxis(); + size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); + size_t count = 0; + for ( ; isegment != processeds.end(); ++isegment ) { + _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() ); + + if ( (axis != (*isegment)->getAxis()) or (layer != (*isegment)->getLayer()) ) { + //_feedthroughs[depth] += 1; + //usedAxis[depth].insert ( axis ); + + count = 0; + axis = (*isegment)->getAxis(); + layer = (*isegment)->getLayer(); + depth = Session::getRoutingGauge()->getLayerDepth(layer); + } + ++count; + } + if ( count ) { + //_feedthroughs[depth] += 1; + //usedAxis[depth].insert ( axis ); + } + } + // Normalize: 0 < d < 1.0 (divide by H/V capacity). for ( size_t i=0 ; i<_depth ; i++ ) { switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { case Constant::Horizontal: - _densities[i] = ((float)uLengths2[i]) / ( hcapacity * (float)_box.getWidth() ); + _densities [i] = ((float)uLengths2[i]) / ( hcapacity * (float)_box.getWidth() ); + _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(); break; case Constant::Vertical: - _densities[i] = ((float)uLengths2[i]) / ( vcapacity * (float)_box.getHeight() ); + _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(); break; } - if ( _densities[i] >= 1.0 ) _saturated = true; + + if ( _densities[i] >= 1.0 ) _saturated = true; + //if ( usedAxis[i].size() > _feedthroughs[i] ) _feedthroughs[i] = usedAxis[i].size(); } _cDensity = ( (float)_contacts.size() ) / ccapacity; _invalid = false; - for ( size_t i=0 ; i<_depth ; i++ ) { - _densities[i] = roundfp ( _densities [i] ); - } + for ( size_t i=0 ; i<_depth ; i++ ) { _densities[i] = roundfp ( _densities[i] ); } _cDensity = roundfp (_cDensity ); ltrace(200) << "updateDensity: " << this << endl; @@ -679,7 +992,7 @@ namespace Katabatic { } } for ( size_t i=3 ; i<_depth ; i+=2 ) { - if ( (_densities[i] < 0.3) and (_densities[i-2] < 0.3) ) continue; + 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) ) { @@ -772,10 +1085,12 @@ namespace Katabatic { ltrace(200) << " | hasFreeTrack [" << getIndex() << "] depth:" << depth << " " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() - << " " << (_densities[depth]*capacity) << " vs. " << capacity + //<< " " << (_densities[depth]*capacity) << " vs. " << capacity + << " " << _feedthroughs[depth] << " vs. " << capacity << " " << this << endl; - return (_densities[depth]*capacity + 1.0 + reserve <= capacity); + //return (_densities[depth]*capacity + 1.0 + reserve <= capacity); + return (_feedthroughs[depth] + 0.99 + reserve <= capacity); } @@ -853,7 +1168,7 @@ namespace Katabatic { } - bool GCell::stepNetDesaturate ( unsigned int depth, set& globalNets, set& invalidateds ) + bool GCell::stepNetDesaturate ( unsigned int depth, set& globalNets, GCell::SetId& invalidateds ) { #if defined(CHECK_DETERMINISM) cerr << "Order: stepDesaturate [" << getIndex() << "] depth:" << depth << endl; @@ -1051,7 +1366,9 @@ namespace Katabatic { #if not defined(CHECK_DETERMINISM) << getDensity(false) << " " #endif - << getVectorString(_densities,_depth) + << "d:" << _depth << " " + << getVectorString(_densities ,_depth) << " " + << getVectorString(_feedthroughs,_depth) << ">"; return s.str(); @@ -1163,15 +1480,22 @@ namespace Katabatic { ltrace(190) << "DyKeyQueue::revalidate()" << endl; std::set::iterator iinserted; - std::set::iterator igcell = _requests.begin(); + GCell::SetId::iterator igcell = _requests.begin(); + + // Remove invalidateds GCell from the queue. for ( ; igcell != _requests.end() ; ++igcell ) { iinserted = _map.find(*igcell); if ( iinserted != _map.end() ) { _map.erase ( iinserted ); } + } + + // Re-insert invalidateds GCell in the queue *after* updating the key. + for ( igcell = _requests.begin() ; igcell != _requests.end() ; ++igcell ) { (*igcell)->updateKey (_depth); _map.insert ( *igcell ); } + _requests.clear (); } diff --git a/katabatic/src/LayerAssign.cpp b/katabatic/src/LayerAssign.cpp index 89f533d2..6dac5e44 100644 --- a/katabatic/src/LayerAssign.cpp +++ b/katabatic/src/LayerAssign.cpp @@ -105,8 +105,8 @@ namespace Katabatic { //vector gcells = *(_gcellGrid->getGCellVector()); //vector invalidateds; - DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) ); - set invalidateds; + DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) ); + GCell::SetId invalidateds; bool optimized = true; while ( optimized ) { @@ -118,8 +118,11 @@ namespace Katabatic { std::set::const_iterator igcell = queue.getGCells().begin(); size_t i = 0; for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) { + ltrace(400) << "_desaturate: [" << depth << "]:" + << (*igcell)->getDensity(depth) << " " << *igcell << endl; + if ( not (*igcell)->isSaturated ( depth ) ) { - ltrace(190) << "STOP desaturated: @" << i << " " << *igcell << endl; + ltrace(400) << "STOP desaturated: @" << i << " " << *igcell << endl; for ( ; igcell!=queue.getGCells().end() ; ++igcell ) { if ( (*igcell)->isSaturated ( depth ) ) { cerr << "[ERROR] Still saturated: @" << i << " " << *igcell << endl; @@ -145,7 +148,7 @@ namespace Katabatic { optimized = (*igcell)->stepNetDesaturate ( depth, globalNets, invalidateds ); if ( optimized ) { - for ( set::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) { + for ( GCell::SetId::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) { queue.invalidate ( *igcell ); } break; @@ -255,18 +258,18 @@ namespace Katabatic { } - bool KatabaticEngine::_moveUpNetTrunk ( AutoSegment* seed, set& globalNets, set& invalidateds ) + bool KatabaticEngine::_moveUpNetTrunk ( AutoSegment* seed, set& globalNets, GCell::SetId& invalidateds ) { Net* net = seed->getNet(); DebugSession::open ( net, 90 ); - ltrace(100) << "_moveUpNetTrunk() - " << seed << endl; + ltrace(400) << "_moveUpNetTrunk() - " << seed << endl; - if ( not seed->canMoveUp(2.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) { + if ( not seed->canMoveUp(1.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) { DebugSession::close (); return false; } - ltracein(100); + ltracein(400); globalNets.insert ( net ); @@ -293,13 +296,13 @@ namespace Katabatic { sort ( locals.begin(), locals.end(), AutoSegment::CompareId() ); for ( size_t i=0 ; icanMoveUp(2.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) { + 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 ); - ltrace(100) << " | Trunk move up G:" << globals[i] << endl; + ltrace(400) << " | Trunk move up G:" << globals[i] << endl; vector gcells; globals[i]->getGCells ( gcells ); @@ -307,19 +310,19 @@ namespace Katabatic { invalidateds.insert ( gcells[j] ); } } else { - ltrace(100) << " | Reject Trunk move up G:" << globals[i] << endl; + ltrace(400) << " | Reject Trunk move up G:" << globals[i] << endl; } } for ( size_t i=0 ; icanPivotUp(2.0,AutoSegment::Propagate|AutoSegment::IgnoreContact) ) { if ( locals[i]->canPivotUp(2.0,AutoSegment::Propagate) ) { unsigned int depth = Session::getRoutingGauge()->getLayerDepth(locals[i]->getLayer()); locals[i]->changeDepth ( depth+2, true, false ); - ltrace(100) << " | Trunk move up L:" << locals[i] << endl; + ltrace(400) << " | Trunk move up L:" << locals[i] << endl; vector gcells; locals[i]->getGCells ( gcells ); @@ -329,7 +332,7 @@ namespace Katabatic { } } - ltraceout(100); + ltraceout(400); DebugSession::close (); return true; @@ -368,10 +371,10 @@ namespace Katabatic { Session::revalidate (); // Look for RoutingPad overload. - vector gcells = *(_gcellGrid->getGCellVector()); - for ( size_t i=0 ; irpDesaturate ( globalNets ); - } + // vector gcells = *(_gcellGrid->getGCellVector()); + // for ( size_t i=0 ; irpDesaturate ( globalNets ); + // } if ( getConfiguration()->getAllowedDepth() > 2) { for ( int i=0 ; i < 3 ; i++ ) { diff --git a/katabatic/src/katabatic/AutoContact.h b/katabatic/src/katabatic/AutoContact.h index c5fffc83..baa32f40 100644 --- a/katabatic/src/katabatic/AutoContact.h +++ b/katabatic/src/katabatic/AutoContact.h @@ -35,6 +35,7 @@ namespace Hurricane { class RoutingPad; } +#include "katabatic/AutoSegment.h" #include "katabatic/AutoContacts.h" #include "katabatic/GCell.h" @@ -193,7 +194,7 @@ namespace Katabatic { bool canHDesalignate (); bool canVDesalignate (); bool canMoveUp ( AutoSegment* moved ) const; - void getLengths ( DbU::Unit* lengths, set& ); + void getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& ); Box getNativeConstraintBox () const; Interval getUConstraints ( unsigned int direction ) const; inline DbU::Unit getCBXMin () const; diff --git a/katabatic/src/katabatic/AutoSegment.h b/katabatic/src/katabatic/AutoSegment.h index c163648a..9d517d1f 100644 --- a/katabatic/src/katabatic/AutoSegment.h +++ b/katabatic/src/katabatic/AutoSegment.h @@ -86,10 +86,11 @@ namespace Katabatic { , ParallelOrExpanded = (1<<2) , ParallelAndLayerChange = (1<<3) }; - enum Flags { Propagate =0x1 - , AllowLocal =0x2 - , AllowTerminal=0x4 - , IgnoreContact=0x8 + enum Flags { Propagate = (1<<0) + , AllowLocal = (1<<1) + , AllowTerminal = (1<<2) + , IgnoreContact = (1<<3) + , PerpandicularFrag = (1<<4) }; @@ -101,6 +102,12 @@ namespace Katabatic { struct CompareByDepthLength : public binary_function { bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; }; + public: + struct CompareByDepthAxis : public binary_function { + bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; + }; + public: + typedef std::set DepthLengthSet; public: // Utilities. diff --git a/katabatic/src/katabatic/GCell.h b/katabatic/src/katabatic/GCell.h index 9beb5ed4..9aec2d84 100644 --- a/katabatic/src/katabatic/GCell.h +++ b/katabatic/src/katabatic/GCell.h @@ -74,6 +74,10 @@ namespace Katabatic { class GCell : public ExtensionGo { public: + class CompareId : public binary_function { + public: + bool operator() ( const GCell* lhs, const GCell* rhs ); + }; class CompareByDensity : public binary_function { public: CompareByDensity ( unsigned int depth ); @@ -96,6 +100,8 @@ namespace Katabatic { inline void update ( GCell*, unsigned int ); friend bool operator< ( const Key&, const Key& ); }; + public: + typedef set SetId; public: // Static Utilities. @@ -135,6 +141,8 @@ namespace Katabatic { inline float getDensity ( unsigned int depth, bool update=true ) const; float getDensity ( bool update=true ) const; inline DbU::Unit getBlockage ( unsigned int depth ) const; + inline float getFragmentation ( unsigned int depth ) const; + inline float getGlobalsCount ( unsigned int depth ) const; float getStiffness () const; inline vector* getVSegments (); inline vector* getHSegments (); @@ -151,6 +159,7 @@ namespace Katabatic { bool checkEdgeSaturation ( float threshold ) const; // Modifiers. void addBlockage ( unsigned int depth, DbU::Unit ); + // void addBlockedAxis ( unsigned int depth, DbU::Unit ); inline void addVSegment ( AutoSegment* ); inline void addHSegment ( AutoSegment* ); inline void addContact ( AutoContact* ); @@ -162,7 +171,7 @@ namespace Katabatic { inline void updateKey ( unsigned int depth ); void desaturate ( unsigned int depth, set& ); bool stepDesaturate ( unsigned int depth, set&, AutoSegment*& moved, bool force=false ); - bool stepNetDesaturate ( unsigned int depth, set&, set& invalidateds ); + bool stepNetDesaturate ( unsigned int depth, set&, SetId& invalidateds ); void rpDesaturate ( set& ); inline void invalidate (); // Inspector Management. @@ -171,6 +180,17 @@ namespace Katabatic { inline string _getTypeName () const; void _xmlWrite ( ostream& o ) const; + private: + class BlockedAxis { + public: + BlockedAxis ( GCell* ); + const set& getAxisSet ( size_t depth ) const; + void addAxis ( size_t depth, DbU::Unit ); + private: + GCell* _gcell; + set** _axisSets; + }; + private: // Static Attributes. static const Name _goName; @@ -188,6 +208,10 @@ namespace Katabatic { DbU::Unit* _blockages; float _cDensity; float* _densities; + float* _feedthroughs; + float* _fragmentations; + float* _globalsCount; + //BlockedAxis _blockedAxis; //float* _saturateDensities; bool _saturated; bool _invalid; @@ -245,6 +269,12 @@ namespace Katabatic { inline float GCell::getDensity ( unsigned int depth, bool update ) const { if (_invalid and update) const_cast(this)->updateDensity(); return _densities[depth]; } + inline float GCell::getFragmentation ( unsigned int depth ) const + { if (_invalid) const_cast(this)->updateDensity(); return _fragmentations[depth]; } + + inline float GCell::getGlobalsCount ( unsigned int depth ) const + { if (_invalid) const_cast(this)->updateDensity(); return _globalsCount[depth]; } + inline DbU::Unit GCell::getBlockage ( unsigned int depth ) const { return (depth<_depth) ? _blockages[depth] : 0; } @@ -258,6 +288,11 @@ namespace Katabatic { { invalidate(); _contacts.push_back(contact); } +// GCell::CompareId Inline Functions. + inline bool GCell::CompareId::operator() ( const GCell* lhs, const GCell* rhs ) + { return ( lhs->getIndex() < rhs->getIndex() ); } + + // GCell::Key Inline Functions. inline GCell::Key::Key ( float density, unsigned int index ) : _density(density), _index(index) {} inline float GCell::Key::getDensity () const { return _density; } @@ -291,7 +326,7 @@ namespace Katabatic { private: unsigned int _depth; std::set _map; - std::set _requests; + GCell::SetId _requests; }; diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index 7f8a71c7..a8b9e76b 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -51,6 +51,7 @@ namespace CRL { } #include "katabatic/Configuration.h" +#include "katabatic/GCell.h" #include "katabatic/AutoContacts.h" #include "katabatic/AutoSegments.h" #include "katabatic/ChipTools.h" @@ -196,7 +197,7 @@ namespace Katabatic { void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set& ); void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& ); void _layerAssignByTrunk ( Net*, set&, unsigned long& total, unsigned long& global ); - bool _moveUpNetTrunk ( AutoSegment*, set& globalNets, set& invalidateds ); + bool _moveUpNetTrunk ( AutoSegment*, set& globalNets, GCell::SetId& invalidateds ); void _splitContactsOfNet ( Net* ); void _collapseNet ( const Name& , unsigned int depth=1 ); void _collapseNet ( Net* , unsigned int depth=1 );