* ./katabatic:

- New: In LayerAssignement & GCell, perform layer assignment on whole net
        trunk, instead on a segment by segment basis.
    - New: In GCell, fragmentation analysis. When a layer change is requested,
        it allows to check if the additionnal perpandiculars created to
        maintain connexity will not over fragment the layer. This is particu-
        larly critical for M3->M5 which create M4 in perpandiculars, and M4
        may be subject to very dense configuration.
    - New: In AutoSegment & LoadGrByNet, adds a flags telling if the net's
        degree equal 2. Has not proven to be useful yet.
    - New: In AutoSegment, adds a flag telling if the segment is the perpan-
        dicular part of a dogleg. Has not proven useful yet.
This commit is contained in:
Jean-Paul Chaput 2011-01-25 17:16:27 +00:00
parent 10682d9c7c
commit cbccf9e2a4
9 changed files with 172 additions and 50 deletions

View File

@ -2384,7 +2384,7 @@ namespace Katabatic {
length = segment->getLength();
lengths[depth] += length;
if ( abs(length) >= DbU::lambda(50.0) )
cerr << Error("Supicious length:%.2f of %s."
cerr << Error("Suspicious length:%.2f of %s."
,DbU::getLambda(length),getString(autoSegment).c_str()) << endl;
} else {
if ( isHorizontal ) {

View File

@ -759,6 +759,7 @@ namespace Katabatic {
, false
, false
);
segment1->setDogleg ( true );
ltrace(200) << "New " << (void*)dlContact1->getContact() << ":" << dlContact1->getContact() << "." << endl;
ltrace(200) << "New " << (void*)dlContact2->getContact() << ":" << dlContact2->getContact() << "." << endl;

View File

@ -551,10 +551,10 @@ namespace Katabatic {
// Empty constraint interval: ignore.
if ( constraintMin > constraintMax ) return false;
if ( allowOutsideGCell() ) {
if ( isDogleg() ) {
// Ugly: hard-wired value of the track spacing.
constraintMin -= DbU::lambda(5.0) * 8;
constraintMax += DbU::lambda(5.0) * 8;
constraintMin -= DbU::lambda(25.0);
constraintMax += DbU::lambda(25.0);
}
if ( getAxis() < constraintMin ) {
@ -834,7 +834,9 @@ namespace Katabatic {
: _isUnsetAxis (true)
, _invalidated (false)
, _isHorizontal (isHorizontal)
, _isTopologicEnd (false)
, _isTerminal (terminal)
, _isDogleg (false)
, _isCollapsed (collapsed)
, _isCanonical (false)
, _isFixed (false)
@ -1265,6 +1267,42 @@ namespace Katabatic {
}
float AutoSegment::getMaxUnderDensity ( unsigned int flags )
{
ltrace(200) << "AutoSegment::getMaxUnderDensity() " << endl;
GCell* begin = NULL;
GCell* end = NULL;
size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer());
vector<GCell*> gcells;
getGCells ( gcells );
begin = *gcells.begin ();
end = *gcells.rbegin();
float maxDensity = 0.0;
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
maxDensity = std::max ( maxDensity, gcells[i]->getFeedthroughs(depth) );
}
if ( flags & Propagate ) {
forEach ( AutoSegment*, isegment, getCollapseds() ) {
isegment->getGCells ( gcells );
if ( (*gcells.begin ())->getIndex() < begin->getIndex() ) begin = *gcells.begin ();
if ( (*gcells.rbegin())->getIndex() > end ->getIndex() ) end = *gcells.rbegin();
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
maxDensity = std::max ( maxDensity, gcells[i]->getFeedthroughs(depth) );
}
}
}
return maxDensity;
}
bool AutoSegment::canPivotUp ( float reserve, unsigned int flags )
{
ltrace(200) << "AutoSegment::canPivotUp() - " << flags
@ -1445,7 +1483,7 @@ namespace Katabatic {
bool AutoSegment::moveUp ( unsigned int flags )
{
if ( not canMoveUp(0.0,flags) ) return false;
//if ( not canMoveUp(0.0,flags) ) return false;
changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2, flags&Propagate );
return true;
@ -1454,7 +1492,7 @@ namespace Katabatic {
bool AutoSegment::moveDown ( unsigned int flags )
{
if ( not canPivotDown(0.0,flags) ) return false;
//if ( not canPivotDown(0.0,flags) ) return false;
changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) - 2, flags&Propagate );
return true;
@ -1672,14 +1710,15 @@ namespace Katabatic {
string s = getSegment()->_getString();
s.insert ( 1, "id: " );
s.insert ( 4, getString(_id) );
s.insert ( s.size()-1, (_isFixed )?" F":" -" );
s.insert ( s.size()-1, (_strap )? "S": "-" );
s.insert ( s.size()-1, (_isCanonical)? "C": "-" );
s.insert ( s.size()-1, (_isCollapsed)? "c": "-" );
s.insert ( s.size()-1, (_isGlobal) ? "g": "-" );
s.insert ( s.size()-1, (_isTerminal) ? "t": "-" );
s.insert ( s.size()-1, (_slackened) ? "S": "-" );
s.insert ( s.size()-1, (_invalidated)? "i": "-" );
s.insert ( s.size()-1, (_isFixed )?" F":" -" );
s.insert ( s.size()-1, (_strap )? "S": "-" );
s.insert ( s.size()-1, (_isCanonical )? "C": "-" );
s.insert ( s.size()-1, (_isCollapsed )? "c": "-" );
s.insert ( s.size()-1, (_isGlobal )? "g": "-" );
s.insert ( s.size()-1, (_isTopologicEnd)? "e": "-" );
s.insert ( s.size()-1, (_isTerminal )? "t": "-" );
s.insert ( s.size()-1, (_slackened )? "S": "-" );
s.insert ( s.size()-1, (_invalidated )? "i": "-" );
return s;
}

View File

@ -668,6 +668,7 @@ namespace Katabatic {
, false
, false
);
segment1->setDogleg ( true );
ltrace(200) << "New " << (void*)dlContact1->getContact() << ":" << dlContact1->getContact() << "." << endl;
ltrace(200) << "New " << (void*)dlContact2->getContact() << ":" << dlContact2->getContact() << "." << endl;
ltrace(200) << "Session::dogLeg() perpand: " << segment1 << endl;

View File

@ -98,8 +98,7 @@ namespace {
void merge ( DbU::Unit axis, const Interval& );
private:
vector<Axis*> _axiss;
DbU::Unit _min;
DbU::Unit _max;
Interval _span;
size_t _capacity;
size_t _globals;
};
@ -120,6 +119,9 @@ namespace {
void UsedFragments::Axis::merge ( const Interval& chunkMerge )
{
// cerr << " Merge @" << DbU::getValueString(_axis)
// << " " << chunkMerge << endl;
list<Interval>::iterator imerge = _chunks.end();
list<Interval>::iterator ichunk = _chunks.begin();
@ -155,9 +157,15 @@ namespace {
list<Interval>::const_iterator inext = ichunk;
++inext;
if ( inext == iend ) break;
Interval currentFree ( (*ichunk).getVMax(), (*inext).getVMin() );
if ( currentFree.getSize() > maxFree.getSize() )
maxFree = currentFree;
// cerr << " @" << DbU::getValueString(_axis)
// << " before:" << *ichunk << " after:" << *inext
// << " size:" << DbU::getValueString(currentFree.getSize()) << endl;
}
return maxFree;
@ -182,8 +190,7 @@ namespace {
UsedFragments::UsedFragments ()
: _axiss ()
, _min (DbU::Min)
, _max (DbU::Max)
, _span (false)
, _capacity(0)
, _globals (0)
{ }
@ -198,15 +205,18 @@ namespace {
}
inline DbU::Unit UsedFragments::getMin () const { return _min; }
inline DbU::Unit UsedFragments::getMax () const { return _max; }
inline void UsedFragments::setSpan ( DbU::Unit min, DbU::Unit max ) { _min=min; _max=max; }
inline DbU::Unit UsedFragments::getMin () const { return _span.getVMin(); }
inline DbU::Unit UsedFragments::getMax () const { return _span.getVMax(); }
inline void UsedFragments::setSpan ( DbU::Unit min, DbU::Unit max ) { _span=Interval(min,max); }
inline void UsedFragments::setCapacity ( size_t capacity ) { _capacity=capacity; }
inline void UsedFragments::incGlobals ( size_t count ) { _globals+=count; }
void UsedFragments::merge ( DbU::Unit axis, const Interval& chunkMerge )
{
Interval restrict = chunkMerge.getIntersection(_span);
if ( restrict.isEmpty() ) return;
vector<Axis*>::iterator iaxis = find_if ( _axiss.begin(), _axiss.end(), AxisMatch(axis) );
Axis* paxis = NULL;
@ -218,14 +228,15 @@ namespace {
paxis = *iaxis;
}
paxis->merge ( chunkMerge );
paxis->merge ( restrict );
}
Interval UsedFragments::getMaxFree () const
{
if ( _capacity > _globals + _axiss.size() )
return Interval(_min,_max);
//cerr << "capacity:" << _capacity << " _globals:" << _globals << " _axiss:" << _axiss.size() << endl;
if ( _capacity > _globals + _axiss.size() + 1 )
return _span;
Interval maxFree;
vector<Axis*>::const_iterator iaxis = _axiss.begin();
@ -909,8 +920,8 @@ namespace Katabatic {
_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
localCounts [depth] += 1.0;
if ( (*isegment)->isGlobal() ) _globalsCount[depth] += 1.0;
ufragments[depth].merge ( (*isegment)->getAxis(), (*isegment)->getSpanU() );
ufragments[depth].merge ( (*isegment)->getAxis(), (*isegment)->getSpanU() );
if ( (axis != (*isegment)->getAxis()) or (layer != (*isegment)->getLayer()) ) {
//_feedthroughs[depth] += 1;
//usedAxis[depth].insert ( axis );
@ -936,12 +947,34 @@ namespace Katabatic {
_feedthroughs [i] += (float)(_blockages[i] / _box.getWidth());
//_fragmentations[i] = (hcapacity - _feedthroughs[i]) / (localCounts[i] + 1.0);
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)_box.getWidth();
// if ( ((float)ufragments[i].getMaxFree().getSize() + (float)uLengths2[i])
// > ( hcapacity * (float)_box.getWidth() ) ) {
// cerr << "INCOHERENCY: " << this << "\n "
// << "on d:" << i
// << " frag:" << DbU::getValueString(ufragments[i].getMaxFree().getSize())
// << " ulength2:" << DbU::getValueString(uLengths2[i])
// << " capacity:" << DbU::getValueString(hcapacity * _box.getWidth())
// << " " << getVectorString(_fragmentations,_depth) << endl;
// }
break;
case Constant::Vertical:
_densities [i] = ((float)uLengths2[i]) / ( vcapacity * (float)_box.getHeight() );
_feedthroughs [i] += (float)(_blockages[i] / _box.getHeight());
//_fragmentations[i] = (vcapacity - _feedthroughs[i]) / (localCounts[i] + 1.0);
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)_box.getHeight();
// if ( ((float)ufragments[i].getMaxFree().getSize() + (float)uLengths2[i])
// > ( vcapacity * (float)_box.getHeight() ) ) {
// cerr << "INCOHERENCY: " << this << "\n "
// << " on d:" << i
// << " frag:" << DbU::getValueString(ufragments[i].getMaxFree().getSize())
// << " ulength2:" << DbU::getValueString(uLengths2[i])
// << " capacity:" << DbU::getValueString(vcapacity * _box.getHeight())
// << " " << getVectorString(_fragmentations,_depth) << endl;
// }
break;
}
@ -955,7 +988,7 @@ namespace Katabatic {
for ( size_t i=0 ; i<_depth ; i++ ) { _densities[i] = roundfp ( _densities[i] ); }
_cDensity = roundfp (_cDensity );
ltrace(200) << "updateDensity: " << this << endl;
ltrace(190) << "updateDensity: " << this << endl;
checkDensity ();
@ -991,25 +1024,25 @@ namespace Katabatic {
<< endl;
}
}
for ( size_t i=3 ; i<_depth ; i+=2 ) {
if ( (_densities[i] < 0.5) and (_densities[i-2] < 0.5) ) continue;
// for ( size_t i=3 ; i<_depth ; i+=2 ) {
// if ( (_densities[i] < 0.5) and (_densities[i-2] < 0.5) ) continue;
float balance = _densities[i] / (_densities[i-2]+0.001 );
if ( (balance > 3) or (balance < .33) ) {
cerr << Warning("%s @%dx%d unbalanced in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)"
,_getString().c_str()
,getColumn()
,getRow()
,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str()
,_densities[1] // M2
,_densities[2] // M3
//,_blockages[2] // M4
,_densities[3] // M5
,_densities[4] // M6
)
<< endl;
}
}
// float balance = _densities[i] / (_densities[i-2]+0.001 );
// if ( (balance > 3) or (balance < .33) ) {
// cerr << Warning("%s @%dx%d unbalanced in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)"
// ,_getString().c_str()
// ,getColumn()
// ,getRow()
// ,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str()
// ,_densities[1] // M2
// ,_densities[2] // M3
// //,_blockages[2] // M4
// ,_densities[3] // M5
// ,_densities[4] // M6
// )
// << endl;
// }
// }
}
return ( _saturated ) ? 1 : 0 ;

View File

@ -298,6 +298,8 @@ namespace Katabatic {
for ( size_t i=0 ; i<globals.size() ; ++i ) {
ltrace(400) << " | Looking up G:" << globals[i] << endl;
if ( globals[i]->isVertical() and (globals[i] != seed) ) continue;
if ( globals[i]->canMoveUp(1.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) {
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(globals[i]->getLayer());
globals[i]->changeDepth ( depth+2, true, false );
@ -319,6 +321,10 @@ namespace Katabatic {
//if ( locals[i]->canPivotUp(2.0,AutoSegment::Propagate|AutoSegment::IgnoreContact) ) {
if ( locals[i]->canPivotUp(2.0,AutoSegment::Propagate) ) {
//if ( locals[i]->isGlobal() and locals[i]->isTopologicEnd() ) continue;
// if ( (locals[i]->isGlobal())
// and (locals[i]->getMaxUnderDensity(AutoSegment::Propagate) < 5.0) ) continue;
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(locals[i]->getLayer());
locals[i]->changeDepth ( depth+2, true, false );

View File

@ -2,13 +2,13 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
// | |
// | C O R I O L I S |
// | K a t a b a t i c - Routing Toolbox |
@ -20,7 +20,7 @@
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
#include <cstdlib>
@ -1094,13 +1094,14 @@ namespace {
public:
// Methods.
static void init ( unsigned int degree );
static void fixSegments ();
GCellConfiguration ( GCellGrid* gcellGrid
, Hook* fromHook
, AutoContact* sourceContact=NULL );
void construct ( ForkStack& forks );
inline unsigned int getStateG () const;
inline GCell* getGCell () const;
static void fixSegments ();
static bool _GCell_rp_AutoContacts ( GCell* gcell
, RoutingPad* rp
, AutoContact*& source
@ -1234,6 +1235,8 @@ namespace {
// Attributes.
private:
static vector<AutoSegment*> _toFixSegments;
static bool _onTopologicEnd;
static unsigned int _degree;
UState _state;
unsigned int _topology;
Net* _net;
@ -1255,6 +1258,8 @@ namespace {
vector<AutoSegment*> GCellConfiguration::_toFixSegments;
bool GCellConfiguration::_onTopologicEnd = false;
unsigned int GCellConfiguration::_degree = 0;
void GCellConfiguration::fixSegments ()
@ -1265,6 +1270,14 @@ namespace {
}
void GCellConfiguration::init ( unsigned int degree )
{
_degree = degree;
_onTopologicEnd = false;
_toFixSegments.clear ();
}
GCellConfiguration::GCellConfiguration ( GCellGrid* gcellGrid
, Hook* fromHook
, AutoContact* sourceContact )
@ -1344,6 +1357,7 @@ namespace {
if (_state.fields.globals == 1) {
if ( _north || _south ) _topology |= GLOBAL_VERTICAL_END;
else _topology |= GLOBAL_HORIZONTAL_END;
_onTopologicEnd = true;
} else if (_state.fields.globals == 2) {
if ( _east && _west ) _topology |= GLOBAL_HORIZONTAL;
else if ( _north && _south ) _topology |= GLOBAL_VERTICAL;
@ -1454,6 +1468,10 @@ namespace {
, targetContact
, static_cast<Segment*>( _fromHook->getComponent() )
);
globalSegment->setTopologicEnd ( _onTopologicEnd );
_onTopologicEnd = false;
globalSegment->setBipoint ( (_degree == 2) );
ltrace(99) << "Create global segment: " << globalSegment << endl;
if ( globalSegment->isHorizontal()
@ -2482,8 +2500,9 @@ namespace Katabatic {
lookupClear ();
RoutingPads routingPads = net->getRoutingPads ();
if ( routingPads.getSize() < 2 ) {
RoutingPads routingPads = net->getRoutingPads ();
size_t degree = routingPads.getSize();
if ( degree < 2 ) {
#if 0
if ( !getDemoMode() )
cmess2 << Warning("Net \"%s\" have less than 2 plugs/pins (ignored)."
@ -2498,6 +2517,9 @@ namespace Katabatic {
GCell* lowestGCell = NULL;
size_t unconnecteds = 0;
size_t connecteds = 0;
GCellConfiguration::init ( degree );
ltrace(99) << "Start RoutingPad Ring" << endl;
forEach ( RoutingPad*, startRp, routingPads ) {
bool segmentFound = false;

View File

@ -186,11 +186,14 @@ namespace Katabatic {
// Predicates.
inline bool isHorizontal () const;
inline bool isVertical () const;
inline bool isBipoint () const;
inline bool isTopologicEnd () const;
inline bool isInvalidated () const;
inline bool isGlobal () const;
inline bool isLocal () const;
inline bool isCanonicalLocal () const;
inline bool isTerminal () const;
inline bool isDogleg () const;
inline bool isCollapsed () const;
inline bool isCanonical () const;
inline bool isFixed () const;
@ -211,6 +214,7 @@ namespace Katabatic {
bool canSlacken ( bool propagate=false );
virtual bool _canSlacken () const = 0;
bool canGoOutsideGCell () const;
float getMaxUnderDensity ( unsigned int flags );
// Accessors.
inline unsigned long getId () const;
virtual unsigned int getDirection () const = 0;
@ -252,10 +256,13 @@ namespace Katabatic {
// Static Modifiers.
static void setDestroyMode ( bool );
// Modifiers.
inline void setBipoint ( bool );
inline void setTopologicEnd ( bool );
inline void setGlobal ( bool );
inline void setCanonicalLocal ( bool );
inline void setCanonical ( bool );
inline void setTerminal ( bool );
inline void setDogleg ( bool );
inline void setFixed ( bool );
inline void setStrap ( bool );
inline void setLayerChange ( bool );
@ -329,9 +336,12 @@ namespace Katabatic {
bool _isUnsetAxis;
bool _invalidated;
bool _isHorizontal;
bool _isBipoint;
bool _isTopologicEnd;
bool _isGlobal;
bool _isCanonicalLocal;
bool _isTerminal;
bool _isDogleg;
bool _isCollapsed;
bool _isCanonical;
bool _isFixed;
@ -406,11 +416,14 @@ namespace Katabatic {
inline bool AutoSegment::isInvalidated () const { return _invalidated; }
inline bool AutoSegment::isHorizontal () const { return _isHorizontal; }
inline bool AutoSegment::isBipoint () const { return _isBipoint; }
inline bool AutoSegment::isTopologicEnd () const { return _isTopologicEnd; }
inline bool AutoSegment::isVertical () const { return !_isHorizontal; }
inline bool AutoSegment::isGlobal () const { return _isGlobal; }
inline bool AutoSegment::isCanonicalLocal () const { return _isCanonicalLocal; }
inline bool AutoSegment::isLocal () const { return !_isGlobal; }
inline bool AutoSegment::isTerminal () const { return _isTerminal; }
inline bool AutoSegment::isDogleg () const { return _isDogleg ; }
inline bool AutoSegment::isCollapsed () const { return _isCollapsed; }
inline bool AutoSegment::isCanonical () const { return _isCanonical; }
inline bool AutoSegment::isFixed () const { return _isFixed; }
@ -424,9 +437,12 @@ namespace Katabatic {
inline void AutoSegment::setLayer ( const Layer* layer ) { invalidate(); getSegment()->setLayer(layer); }
inline void AutoSegment::setInvalidated ( bool state ) { _invalidated = state; }
inline void AutoSegment::setBipoint ( bool state ) { _isBipoint = state; }
inline void AutoSegment::setTopologicEnd ( bool state ) { _isTopologicEnd = state; }
inline void AutoSegment::setGlobal ( bool state ) { _isGlobal = state; }
inline void AutoSegment::setCanonicalLocal ( bool state ) { _isCanonicalLocal = state; }
inline void AutoSegment::setTerminal ( bool state ) { _isTerminal = state; }
inline void AutoSegment::setDogleg ( bool state ) { _isDogleg = state; }
inline void AutoSegment::setFixed ( bool state ) { _isFixed = state; }
inline void AutoSegment::setStrap ( bool state ) { _strap = state; }
inline void AutoSegment::setLayerChange ( bool state ) { _layerChange = state; }

View File

@ -142,6 +142,7 @@ namespace Katabatic {
float getDensity ( bool update=true ) const;
inline DbU::Unit getBlockage ( unsigned int depth ) const;
inline float getFragmentation ( unsigned int depth ) const;
inline float getFeedthroughs ( unsigned int depth ) const;
inline float getGlobalsCount ( unsigned int depth ) const;
float getStiffness () const;
inline vector<AutoSegment*>* getVSegments ();
@ -272,6 +273,9 @@ namespace Katabatic {
inline float GCell::getFragmentation ( unsigned int depth ) const
{ if (_invalid) const_cast<GCell*>(this)->updateDensity(); return _fragmentations[depth]; }
inline float GCell::getFeedthroughs ( unsigned int depth ) const
{ if (_invalid) const_cast<GCell*>(this)->updateDensity(); return _feedthroughs[depth]; }
inline float GCell::getGlobalsCount ( unsigned int depth ) const
{ if (_invalid) const_cast<GCell*>(this)->updateDensity(); return _globalsCount[depth]; }