* ./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().
This commit is contained in:
Jean-Paul Chaput 2011-01-09 18:08:31 +00:00
parent e6ac57145f
commit 0df293655a
8 changed files with 499 additions and 65 deletions

View File

@ -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<SegmentEnd*> 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<AutoSegment*>& processeds )
void AutoContact::getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& processeds )
{
forEach ( Hook*, ihook, getBodyHook()->getSlaveHooks() ) {
bool isSourceHook = (dynamic_cast<Segment::SourceHook*>(*ihook));

View File

@ -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<GCell*> gcells;
getGCells ( gcells );
begin = *gcells.begin ();
end = *gcells.rbegin();
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
if ( not gcells[i]->hasFreeTrack(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 ; i<gcells.size() ; i++ ) {
if ( not gcells[i]->hasFreeTrack(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<Segment*>(*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 <AutoSegment> 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;
}

View File

@ -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<Interval> _chunks;
};
private:
class AxisCompare {
public:
bool operator() ( const Axis* lhs, const Axis* rhs );
};
class AxisMatch : public unary_function<Axis*,bool> {
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<Axis*> _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<Interval>::iterator imerge = _chunks.end();
list<Interval>::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<Interval>::const_iterator ichunk = _chunks.begin();
list<Interval>::const_iterator iend = --_chunks.end();
Interval maxFree;
for ( ; ichunk != iend ; ++ichunk ) {
list<Interval>::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<Axis*>::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<Axis*>::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<DbU::Unit>* [_gcell->getDepth()])
{
for ( size_t i=0 ; i<_gcell->getDepth() ; ++i ) _axisSets[i] = NULL;
}
const set<DbU::Unit>& GCell::BlockedAxis::getAxisSet ( size_t depth ) const
{
static const set<DbU::Unit> _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<DbU::Unit>();
_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<DbU::Unit> 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<AutoSegment*> processeds;
AutoSegment::DepthLengthSet processeds;
vector<AutoContact*>::iterator it = _contacts.begin();
vector<AutoContact*>::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<Net*>& globalNets, set<GCell*>& invalidateds )
bool GCell::stepNetDesaturate ( unsigned int depth, set<Net*>& 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<GCell*,GCell::CompareByKey>::iterator iinserted;
std::set<GCell*>::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 ();
}

View File

@ -105,8 +105,8 @@ namespace Katabatic {
//vector<GCell*> gcells = *(_gcellGrid->getGCellVector());
//vector<GCell*> invalidateds;
DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) );
set<GCell*> invalidateds;
DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) );
GCell::SetId invalidateds;
bool optimized = true;
while ( optimized ) {
@ -118,8 +118,11 @@ namespace Katabatic {
std::set<GCell*,GCell::CompareByKey>::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<GCell*>::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<Net*>& globalNets, set<GCell*>& invalidateds )
bool KatabaticEngine::_moveUpNetTrunk ( AutoSegment* seed, set<Net*>& 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 ; i<globals.size() ; ++i ) {
ltrace(100) << " | Looking up G:" << globals[i] << endl;
ltrace(400) << " | Looking up G:" << globals[i] << endl;
if ( globals[i]->canMoveUp(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<GCell*> 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 ; i<locals.size() ; ++i ) {
ltrace(100) << " | Looking up L:" << locals[i] << endl;
ltrace(400) << " | Looking up L:" << locals[i] << endl;
//if ( locals[i]->canPivotUp(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<GCell*> 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<GCell*> gcells = *(_gcellGrid->getGCellVector());
for ( size_t i=0 ; i<gcells.size() ; ++i ) {
gcells[i]->rpDesaturate ( globalNets );
}
// vector<GCell*> gcells = *(_gcellGrid->getGCellVector());
// for ( size_t i=0 ; i<gcells.size() ; ++i ) {
// gcells[i]->rpDesaturate ( globalNets );
// }
if ( getConfiguration()->getAllowedDepth() > 2) {
for ( int i=0 ; i < 3 ; i++ ) {

View File

@ -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<AutoSegment*>& );
void getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& );
Box getNativeConstraintBox () const;
Interval getUConstraints ( unsigned int direction ) const;
inline DbU::Unit getCBXMin () const;

View File

@ -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<AutoSegment*,AutoSegment*,bool> {
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
};
public:
struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> {
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
};
public:
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
public:
// Utilities.

View File

@ -74,6 +74,10 @@ namespace Katabatic {
class GCell : public ExtensionGo {
public:
class CompareId : public binary_function<const GCell*,const GCell*,bool> {
public:
bool operator() ( const GCell* lhs, const GCell* rhs );
};
class CompareByDensity : public binary_function<GCell*,GCell*,bool> {
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<GCell*,CompareId> 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<AutoSegment*>* getVSegments ();
inline vector<AutoSegment*>* 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<Net*>& );
bool stepDesaturate ( unsigned int depth, set<Net*>&, AutoSegment*& moved, bool force=false );
bool stepNetDesaturate ( unsigned int depth, set<Net*>&, set<GCell*>& invalidateds );
bool stepNetDesaturate ( unsigned int depth, set<Net*>&, SetId& invalidateds );
void rpDesaturate ( set<Net*>& );
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<DbU::Unit>& getAxisSet ( size_t depth ) const;
void addAxis ( size_t depth, DbU::Unit );
private:
GCell* _gcell;
set<DbU::Unit>** _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<GCell*>(this)->updateDensity(); return _densities[depth]; }
inline float GCell::getFragmentation ( unsigned int depth ) const
{ if (_invalid) const_cast<GCell*>(this)->updateDensity(); return _fragmentations[depth]; }
inline float GCell::getGlobalsCount ( unsigned int depth ) const
{ if (_invalid) const_cast<GCell*>(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<GCell*,GCell::CompareByKey> _map;
std::set<GCell*> _requests;
GCell::SetId _requests;
};

View File

@ -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<Net*>& );
void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByTrunk ( Net*, set<Net*>&, unsigned long& total, unsigned long& global );
bool _moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, set<GCell*>& invalidateds );
bool _moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::SetId& invalidateds );
void _splitContactsOfNet ( Net* );
void _collapseNet ( const Name& , unsigned int depth=1 );
void _collapseNet ( Net* , unsigned int depth=1 );