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;