From 37b4e5b423da2008cd75e1821af47824d728961d Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 3 May 2010 09:16:50 +0000 Subject: [PATCH] * ./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. --- kite/src/NegociateWindow.cpp | 2 +- kite/src/RoutingEvent.cpp | 125 ++++++++++++++++++++++--------- kite/src/RoutingEventHistory.cpp | 2 +- kite/src/TrackCost.cpp | 13 +++- kite/src/kite/DataNegociate.h | 72 +++++++++--------- kite/src/kite/RoutingEvent.h | 2 +- kite/src/kite/TrackCost.h | 2 +- kite/src/kite/TrackSegmentCost.h | 4 +- 8 files changed, 144 insertions(+), 78 deletions(-) diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index 925aba99..03d927b1 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -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":"-") diff --git a/kite/src/RoutingEvent.cpp b/kite/src/RoutingEvent.cpp index f323b6be..34e34358 100644 --- a/kite/src/RoutingEvent.cpp +++ b/kite/src/RoutingEvent.cpp @@ -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 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& doglegs = Session::getDogLegs(); for ( size_t i=0 ; igetGCell()->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 gcells; + _segment->getGCells ( gcells ); + + size_t igcell = 0; + for ( ; igcellgetUSide(_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; diff --git a/kite/src/RoutingEventHistory.cpp b/kite/src/RoutingEventHistory.cpp index 0b6851d8..5ac87ae0 100644 --- a/kite/src/RoutingEventHistory.cpp +++ b/kite/src/RoutingEventHistory.cpp @@ -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 // // =================================================================== // diff --git a/kite/src/TrackCost.cpp b/kite/src/TrackCost.cpp index e2e6f821..d4aea624 100644 --- a/kite/src/TrackCost.cpp +++ b/kite/src/TrackCost.cpp @@ -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":"-" ); diff --git a/kite/src/kite/DataNegociate.h b/kite/src/kite/DataNegociate.h index 45660684..a0e6dd63 100644 --- a/kite/src/kite/DataNegociate.h +++ b/kite/src/kite/DataNegociate.h @@ -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. diff --git a/kite/src/kite/RoutingEvent.h b/kite/src/kite/RoutingEvent.h index d84169b1..7e68bc58 100644 --- a/kite/src/kite/RoutingEvent.h +++ b/kite/src/kite/RoutingEvent.h @@ -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 // // =================================================================== // diff --git a/kite/src/kite/TrackCost.h b/kite/src/kite/TrackCost.h index 01a6edf4..d6c3b74e 100644 --- a/kite/src/kite/TrackCost.h +++ b/kite/src/kite/TrackCost.h @@ -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 // // =================================================================== // diff --git a/kite/src/kite/TrackSegmentCost.h b/kite/src/kite/TrackSegmentCost.h index 0e59ef1b..5e554b1d 100644 --- a/kite/src/kite/TrackSegmentCost.h +++ b/kite/src/kite/TrackSegmentCost.h @@ -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;