* ./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:
parent
e6ac57145f
commit
0df293655a
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
|
@ -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++ ) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue