* ./kite:
- Change: In TrackCost, the ripup cost is now computed from a mix between the number of ripup *and* the data state. Restore a correct balance of the ripping up between segments. - New: In RoutingEvent::State::conflictSolve1(), when a very long Segment enters in conflictSolve1(), still prefers to move it up in one piece, but if it's not possible, it is unlikely that it will overlap with only one or two other Segment. In that cases, blindy break it up in the middle. - New: In RoutingEvent::Manipulator, another overload of makeDogLeg to allow break up at one precise point. - Change/Bug: In RoutingEvent::Manipulator::Relax(), reset the state of the non-overlapping Segment fragments instead of inheriting blindly of the state of the breaked up one. Gives some supplemental slack that allows to converge. - Note: Now the strategy is to disable the uses of GCellRoutingSet by setting the expand step to 0.99. This induces only a slight slow dow and memory increase and passes all the tests... - Mark: This revision passes all the benches except for idct, vld & ieee_division.
This commit is contained in:
parent
234175fa23
commit
37b4e5b423
|
@ -404,7 +404,7 @@ namespace Kite {
|
|||
count = 0;
|
||||
|
||||
ltrace(200) << "Dumping history." << endl;
|
||||
for ( size_t i=0 ; (i<_eventHistory.size()) && !isInterrupted() ; i++ ) {
|
||||
for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) {
|
||||
RoutingEvent* event = _eventHistory.getNth(i);
|
||||
ltrace(200) << (void*)event << " ["
|
||||
<< (event->isCloned ()?"C":"-")
|
||||
|
|
|
@ -827,6 +827,7 @@ namespace {
|
|||
bool pivotUp ();
|
||||
bool moveUp ();
|
||||
bool makeDogLeg ();
|
||||
bool makeDogLeg ( DbU::Unit );
|
||||
bool makeDogLeg ( Interval );
|
||||
bool relax ( Interval, unsigned int flags=AllowExpand );
|
||||
bool relax ( size_t );
|
||||
|
@ -1128,7 +1129,6 @@ namespace {
|
|||
bool State::conflictSolve1 ()
|
||||
{
|
||||
bool success = false;
|
||||
bool constraintByPerpandiculars = false;
|
||||
Interval constraints;
|
||||
vector<Cs1Candidate> candidates;
|
||||
TrackElement* segment = _event->getSegment();
|
||||
|
@ -1244,7 +1244,15 @@ namespace {
|
|||
//if ( track && (track->getAxis() < constraints.getVMin()) ) track = track->getNext();
|
||||
//for ( ; !success && track && (track->getAxis() <= constraints.getVMax()) ; track = track->getNext() )
|
||||
|
||||
if ( not success and constraintByPerpandiculars ) {
|
||||
if ( not success and (segment->getLength() >= Session::getConfiguration()->getGlobalThreshold()) ) {
|
||||
ltrace(200) << "Long global wire, break in the middle." << endl;
|
||||
Interval span;
|
||||
segment->getCanonical ( span );
|
||||
|
||||
success = Manipulator(segment,*this).makeDogLeg ( span.getCenter() );
|
||||
}
|
||||
|
||||
if ( not success and segment->isGlobal() and (_costs.size() <= 1) ) {
|
||||
ltrace(200) << "Overconstrained perpandiculars, rip them up. On track:" << endl;
|
||||
ltrace(200) << " " << track << endl;
|
||||
Manipulator(segment,*this).ripupPerpandiculars ();
|
||||
|
@ -1333,8 +1341,10 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
if ( candidate )
|
||||
if ( candidate ) {
|
||||
ltrace(200) << "> Accept candidate " << candidate << endl;
|
||||
candidates.push_back ( LvGCandidate(candidate,otherOverlap,terminals) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( candidates.empty() ) {
|
||||
|
@ -1595,6 +1605,8 @@ namespace {
|
|||
nextState = DataNegociate::ConflictSolve1;
|
||||
break;
|
||||
}
|
||||
nextState = DataNegociate::MaximumSlack;
|
||||
break;
|
||||
case DataNegociate::MaximumSlack:
|
||||
case DataNegociate::Unimplemented:
|
||||
ltrace(200) << "Global, State: MaximumSlack or Unimplemented." << endl;
|
||||
|
@ -2132,47 +2144,51 @@ namespace {
|
|||
|
||||
// Making first dogleg.
|
||||
ltrace(200) << "Making FIRST dogleg at " << ifirstDogleg << endl;
|
||||
TrackElement* segment = _segment;
|
||||
Track* track = _segment->getTrack();
|
||||
GCell* dogLegGCell = gcells[ifirstDogleg];
|
||||
TrackElement* dogleg = NULL;
|
||||
TrackElement* segment1 = NULL;
|
||||
TrackElement* segment2 = NULL;
|
||||
Track* track = _segment->getTrack();
|
||||
GCell* dogLegGCell = gcells[ifirstDogleg];
|
||||
TrackElement* dogleg = NULL;
|
||||
DbU::Unit doglegAxis;
|
||||
bool doglegReuse = false;
|
||||
bool doglegReuse1 = false;
|
||||
bool doglegReuse2 = false;
|
||||
|
||||
// Try to reuse existing dogleg if broken at either end.
|
||||
if ( ifirstDogleg == 0 ) dogleg = segment->getSourceDogLeg();
|
||||
if ( ifirstDogleg == gcells.size()-1 ) dogleg = segment->getTargetDogLeg();
|
||||
if ( ifirstDogleg == 0 ) dogleg = _segment->getSourceDogLeg();
|
||||
if ( ifirstDogleg == gcells.size()-1 ) dogleg = _segment->getTargetDogLeg();
|
||||
if ( dogleg ) {
|
||||
ltrace(200) << "Reusing dogleg." << endl;
|
||||
doglegReuse = true;
|
||||
doglegReuse1 = true;
|
||||
segment1 = _segment;
|
||||
} else {
|
||||
// Try to create a new dogleg.
|
||||
if ( not segment->canDogLegAt(dogLegGCell) ) {
|
||||
if ( not _segment->canDogLegAt(dogLegGCell) ) {
|
||||
ltrace(200) << "Cannot create FIRST dogleg." << endl;
|
||||
ltraceout(200);
|
||||
return false;
|
||||
}
|
||||
dogleg = segment->makeDogLeg ( dogLegGCell );
|
||||
dogleg = _segment->makeDogLeg ( dogLegGCell );
|
||||
segment1 = Session::lookup ( Session::getDogLegs()[2] );
|
||||
}
|
||||
|
||||
if ( firstDogLegIsMin ) {
|
||||
if ( minExpanded ) {
|
||||
//doglegAxis = dogLegGCell->getUSide(segment->getDirection(),false).getVMax() - DbU::lambda(1.0);
|
||||
doglegAxis = dogLegGCell->getUSide(segment->getDirection(),false).getCenter();
|
||||
//doglegAxis = dogLegGCell->getUSide(_segment->getDirection(),false).getVMax() - DbU::lambda(1.0);
|
||||
doglegAxis = dogLegGCell->getUSide(_segment->getDirection(),false).getCenter();
|
||||
} else {
|
||||
// Ugly: hardcoded pitch.
|
||||
doglegAxis = interval.getVMin() - DbU::lambda(5.0);
|
||||
}
|
||||
} else {
|
||||
if ( maxExpanded ) {
|
||||
doglegAxis = dogLegGCell->getUSide(segment->getDirection(),false).getVMin();
|
||||
doglegAxis = dogLegGCell->getUSide(_segment->getDirection(),false).getVMin();
|
||||
} else {
|
||||
// Ugly: hardcoded pitch (5.0 - 1.0).
|
||||
doglegAxis = interval.getVMax() + DbU::lambda(4.0);
|
||||
}
|
||||
}
|
||||
if ( doglegReuse ) _S.addAction ( dogleg, SegmentAction::OtherRipup );
|
||||
else dogleg->setAxis ( doglegAxis );
|
||||
if ( doglegReuse1 ) _S.addAction ( dogleg, SegmentAction::OtherRipup );
|
||||
else dogleg->setAxis ( doglegAxis );
|
||||
|
||||
// If event is present, the dogleg is in the current RoutingSet.
|
||||
RoutingEvent* event = dogleg->getDataNegociate()->getRoutingEvent();
|
||||
|
@ -2184,49 +2200,49 @@ namespace {
|
|||
}
|
||||
|
||||
if ( (dogLegCount == 2)
|
||||
and not segment->getTrack()
|
||||
and (segment->getGCell()->getOrder() < Session::getOrder()) ) {
|
||||
Session::addInsertEvent ( segment, track );
|
||||
and not _segment->getTrack()
|
||||
and (_segment->getGCell()->getOrder() < Session::getOrder()) ) {
|
||||
Session::addInsertEvent ( _segment, track );
|
||||
}
|
||||
|
||||
// Making second dogleg.
|
||||
if ( dogLegCount > 1 ) {
|
||||
ltrace(200) << "Making SECOND dogleg at " << isecondDogleg
|
||||
<< " on " << Session::getDogLegs()[2] << endl;
|
||||
<< " on " << segment1 << endl;
|
||||
|
||||
dogleg = NULL;
|
||||
segment = Session::lookup ( Session::getDogLegs()[2] );
|
||||
dogLegGCell = gcells[isecondDogleg];
|
||||
|
||||
if ( ifirstDogleg == isecondDogleg ) {
|
||||
ltrace(200) << "Double break in same GCell." << endl;
|
||||
segment->setSourceDogLeg(false);
|
||||
segment1->setSourceDogLeg(false);
|
||||
}
|
||||
|
||||
doglegReuse = false;
|
||||
if ( isecondDogleg == gcells.size()-1 ) dogleg = segment->getTargetDogLeg();
|
||||
if ( isecondDogleg == gcells.size()-1 ) dogleg = segment1->getTargetDogLeg();
|
||||
if ( dogleg ) {
|
||||
ltrace(200) << "Reusing dogleg." << endl;
|
||||
doglegReuse = true;
|
||||
doglegReuse2 = true;
|
||||
segment2 = segment1;
|
||||
} else {
|
||||
// Try to create a new dogleg.
|
||||
if ( not segment->canDogLegAt(dogLegGCell) ) {
|
||||
if ( not segment1->canDogLegAt(dogLegGCell) ) {
|
||||
ltrace(200) << "Cannot create SECOND dogleg." << endl;
|
||||
ltraceout(200);
|
||||
return false;
|
||||
}
|
||||
dogleg = segment->makeDogLeg ( dogLegGCell );
|
||||
dogleg = segment1->makeDogLeg ( dogLegGCell );
|
||||
segment2 = Session::lookup ( Session::getDogLegs()[2] );
|
||||
}
|
||||
|
||||
if ( maxExpanded ) {
|
||||
//doglegAxis = dogLegGCell->getUSide(segment->getDirection(),false).getVMin();
|
||||
doglegAxis = dogLegGCell->getUSide(segment->getDirection(),false).getCenter();
|
||||
//doglegAxis = dogLegGCell->getUSide(segment1->getDirection(),false).getVMin();
|
||||
doglegAxis = dogLegGCell->getUSide(segment1->getDirection(),false).getCenter();
|
||||
} else {
|
||||
// Ugly: hardcoded pitch.
|
||||
doglegAxis = interval.getVMax() + DbU::lambda(5.0);
|
||||
}
|
||||
if ( doglegReuse ) _S.addAction ( dogleg, SegmentAction::OtherRipup );
|
||||
else dogleg->setAxis ( doglegAxis );
|
||||
if ( doglegReuse2 ) _S.addAction ( dogleg, SegmentAction::OtherRipup );
|
||||
else dogleg->setAxis ( doglegAxis );
|
||||
|
||||
// If event is present, the dogleg is in the current RoutingSet.
|
||||
RoutingEvent* event = dogleg->getDataNegociate()->getRoutingEvent();
|
||||
|
@ -2239,12 +2255,30 @@ namespace {
|
|||
|
||||
const vector<AutoSegment*>& doglegs = Session::getDogLegs();
|
||||
for ( size_t i=0 ; i<doglegs.size() ; i++ ) {
|
||||
segment = Session::lookup(doglegs[i]);
|
||||
TrackElement* segment = Session::lookup(doglegs[i]);
|
||||
if ( ( segment->getGCell()->getOrder() < Session::getOrder() ) and not segment->getTrack() ) {
|
||||
Session::addInsertEvent ( segment, track );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch ( dogLegCount ) {
|
||||
case 1:
|
||||
if ( not doglegReuse1 ) {
|
||||
if ( firstDogLegIsMin )
|
||||
_segment->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true );
|
||||
else
|
||||
segment1->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true );
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if ( not doglegReuse1 )
|
||||
_segment->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true );
|
||||
if ( not doglegReuse2 )
|
||||
segment2->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true );
|
||||
break;
|
||||
}
|
||||
|
||||
} else if ( _data->getGCellOrder() > currentOrder ) {
|
||||
cerr << Bug("relax() Routing order problem for %s."
|
||||
,getString(_segment).c_str()) << endl;
|
||||
|
@ -2817,6 +2851,29 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
bool Manipulator::makeDogLeg ( DbU::Unit position )
|
||||
{
|
||||
ltrace(200) << "Manipulator::makeDogLeg(position) " << _segment << endl;
|
||||
ltrace(200) << "Breaking position: " << DbU::getValueString(position) << endl;
|
||||
|
||||
if ( _segment->isFixed() ) return false;
|
||||
|
||||
vector<GCell*> gcells;
|
||||
_segment->getGCells ( gcells );
|
||||
|
||||
size_t igcell = 0;
|
||||
for ( ; igcell<gcells.size() ; igcell++ ) {
|
||||
if ( gcells[igcell]->getUSide(_segment->getDirection(),true).contains(position) )
|
||||
break;
|
||||
}
|
||||
if ( igcell == gcells.size() ) return false;
|
||||
if ( not _segment->canDogLegAt(gcells[igcell]) ) return false;
|
||||
|
||||
TrackElement* dogleg = _segment->makeDogLeg(gcells[igcell]);
|
||||
return ( dogleg != NULL );
|
||||
}
|
||||
|
||||
|
||||
bool Manipulator::minimize ()
|
||||
{
|
||||
ltrace(200) << "Manipulator::minimize() " << _segment << endl;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
|
||||
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
|
||||
//
|
||||
// ===================================================================
|
||||
//
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
|
||||
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
|
||||
//
|
||||
// ===================================================================
|
||||
//
|
||||
|
@ -105,8 +105,14 @@ namespace Kite {
|
|||
if ( lhs._infinite xor rhs._infinite ) return rhs._infinite;
|
||||
if ( lhs._hardOverlap xor rhs._hardOverlap ) return rhs._hardOverlap;
|
||||
|
||||
if ( lhs._ripupCount + (int)Session::getRipupCost() < rhs._ripupCount ) return true;
|
||||
if ( lhs._ripupCount > rhs._ripupCount + (int)Session::getRipupCost() ) return false;
|
||||
int lhsRipupCost = (lhs._dataState<<2) + lhs._ripupCount;
|
||||
int rhsRipupCost = (rhs._dataState<<2) + rhs._ripupCount;
|
||||
|
||||
// if ( lhs._ripupCount + (int)Session::getRipupCost() < rhs._ripupCount ) return true;
|
||||
// if ( lhs._ripupCount > rhs._ripupCount + (int)Session::getRipupCost() ) return false;
|
||||
|
||||
if ( lhsRipupCost + (int)Session::getRipupCost() < rhsRipupCost ) return true;
|
||||
if ( lhsRipupCost > (int)Session::getRipupCost() + rhsRipupCost ) return false;
|
||||
|
||||
if ( lhs._overlap xor rhs._overlap ) return rhs._overlap;
|
||||
|
||||
|
@ -156,7 +162,6 @@ namespace Kite {
|
|||
|
||||
s += " " + getString(_track);
|
||||
s += " " + getString(_ripupCount);
|
||||
s += " " + getString(_ripupCount);
|
||||
s += " " + string ( (_blockage )?"b":"-" );
|
||||
s += string ( (_hardOverlap)?"h":"-" );
|
||||
s += string ( (_overlap )?"o":"-" );
|
||||
|
|
|
@ -78,40 +78,41 @@ namespace Kite {
|
|||
};
|
||||
|
||||
public:
|
||||
DataNegociate ( TrackElement* );
|
||||
~DataNegociate ();
|
||||
inline bool isRing () const;
|
||||
inline bool isBorder () const;
|
||||
inline bool isLeftBorder () const;
|
||||
inline bool isRightBorder () const;
|
||||
inline bool hasRoutingEvent () const;
|
||||
inline RoutingEvent* getRoutingEvent () const;
|
||||
inline TrackElement* getTrackSegment () const;
|
||||
inline Track* getTrack () const;
|
||||
inline TrackSegmentCost& getCost ();
|
||||
inline unsigned int getGCellOrder () const;
|
||||
//inline unsigned int getZ () const;
|
||||
inline unsigned int getState () const;
|
||||
inline unsigned int getStateCount () const;
|
||||
inline unsigned int getRipupCount () const;
|
||||
inline void setGCellOrder ( unsigned int );
|
||||
inline void setState ( unsigned int, bool reset=false );
|
||||
inline void setRing ( bool );
|
||||
inline void setLeftBorder ( bool );
|
||||
inline void setRightBorder ( bool );
|
||||
inline void resetBorder ();
|
||||
inline void setRoutingEvent ( RoutingEvent* );
|
||||
inline void setRipupCount ( unsigned int );
|
||||
inline void incRipupCount ();
|
||||
inline void decRipupCount ();
|
||||
inline void resetRipupCount ();
|
||||
inline void resetStateCount ();
|
||||
inline void invalidate ( bool withPerpandiculars=false, bool withConstraints=false );
|
||||
void update ();
|
||||
static string getStateString ( DataNegociate* );
|
||||
Record* _getRecord () const;
|
||||
string _getString () const;
|
||||
inline string _getTypeName () const;
|
||||
DataNegociate ( TrackElement* );
|
||||
~DataNegociate ();
|
||||
inline bool isRing () const;
|
||||
inline bool isBorder () const;
|
||||
inline bool isLeftBorder () const;
|
||||
inline bool isRightBorder () const;
|
||||
inline bool hasRoutingEvent () const;
|
||||
inline RoutingEvent* getRoutingEvent () const;
|
||||
inline TrackElement* getTrackSegment () const;
|
||||
inline Track* getTrack () const;
|
||||
inline TrackSegmentCost& getCost ();
|
||||
inline unsigned int getGCellOrder () const;
|
||||
//inline unsigned int getZ () const;
|
||||
inline unsigned int getState () const;
|
||||
inline unsigned int getStateCount () const;
|
||||
inline unsigned int getRipupCount () const;
|
||||
inline unsigned int getStateAndRipupCount () const;
|
||||
inline void setGCellOrder ( unsigned int );
|
||||
inline void setState ( unsigned int, bool reset=false );
|
||||
inline void setRing ( bool );
|
||||
inline void setLeftBorder ( bool );
|
||||
inline void setRightBorder ( bool );
|
||||
inline void resetBorder ();
|
||||
inline void setRoutingEvent ( RoutingEvent* );
|
||||
inline void setRipupCount ( unsigned int );
|
||||
inline void incRipupCount ();
|
||||
inline void decRipupCount ();
|
||||
inline void resetRipupCount ();
|
||||
inline void resetStateCount ();
|
||||
inline void invalidate ( bool withPerpandiculars=false, bool withConstraints=false );
|
||||
void update ();
|
||||
static string getStateString ( DataNegociate* );
|
||||
Record* _getRecord () const;
|
||||
string _getString () const;
|
||||
inline string _getTypeName () const;
|
||||
|
||||
protected:
|
||||
// Attributes.
|
||||
|
@ -172,6 +173,9 @@ namespace Kite {
|
|||
_stateCount++;
|
||||
}
|
||||
|
||||
inline unsigned int DataNegociate::getStateAndRipupCount () const
|
||||
{ return (_state << 4) + getRipupCount(); }
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
|
||||
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
|
||||
//
|
||||
// ===================================================================
|
||||
//
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
|
||||
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
|
||||
//
|
||||
// ===================================================================
|
||||
//
|
||||
|
|
|
@ -77,8 +77,8 @@ namespace Kite {
|
|||
|
||||
protected:
|
||||
// Attributes.
|
||||
unsigned int _terminals : 5;
|
||||
unsigned int _ripupCount : 5;
|
||||
unsigned int _terminals : 5;
|
||||
unsigned int _ripupCount : 16;
|
||||
DbU::Unit _leftMinExtend;
|
||||
DbU::Unit _rightMinExtend;
|
||||
Net* _net;
|
||||
|
|
Loading…
Reference in New Issue