From 02eb5c56adcb4202d3ecfb6a6ad9e386abf3c0d6 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 23 Aug 2019 15:43:13 +0200 Subject: [PATCH] Improvements in routing quality for ARMv2a * Change: In Katana::SegmentFsm::_slackenStrap(), make unbreakable segments pass through the LocalVsGlobal state so when other try to ripup them they are prioritary. Otherwise some could go through Unimplemented directly, without allowing other to attempt to make a detour. * Change: In Katana::NegociateWindow::NegociateOverlapCost(), when a global, which is about to be slackened wants to use a track where there is a segment directly connected to a terminal with a significant ripup count, mark it as "AtRipupLimit" so it tries to avoid it. The idea is that globals with high ripup count must avoid terminal segments because it is likely they will be riped up again so they better find another track. This was leading to unsolvable configuration when two segments always want the same track. In this cas, the global would loose. * Bug: In Katana::TrackSegment::canSlacken(), never slacken a segments in non-preferred direction. * Change: In Anabatic::AutoHorizontal::_slacken(), allow slackening of segments which perpandiculars are in non-preferred direction, and not only directly attached to terminals. * Change: In Anabatic::AutoSegment::canMoveUp(), re-allow segments which perpandiculars are in non-preferred direction to be moved up. * Bug: In Katana::Manipulator::moveUp(), when moving up, do not forget to ripup and reschedule said segment. --- anabatic/src/AutoHorizontal.cpp | 71 +++++++++++++++++++++++---------- anabatic/src/AutoSegment.cpp | 4 ++ katana/src/Manipulator.cpp | 5 ++- katana/src/NegociateWindow.cpp | 18 ++++++++- katana/src/RoutingEvent.cpp | 13 +++++- katana/src/SegmentFsm.cpp | 6 +++ katana/src/Track.cpp | 3 +- katana/src/TrackCost.cpp | 4 +- katana/src/TrackSegment.cpp | 1 + katana/src/katana/TrackCost.h | 16 ++++---- 10 files changed, 104 insertions(+), 37 deletions(-) diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index 9e586848..33ac1cbb 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -245,27 +245,35 @@ namespace Anabatic { { cdebug_tabw(149,1); - Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Vertical ); - Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Vertical ); - Interval sourceConstraints = Interval(getAutoSource()->getCBYMin(),getAutoSource()->getCBYMax()); - Interval targetConstraints = Interval(getAutoTarget()->getCBYMin(),getAutoTarget()->getCBYMax()); - bool sourceGoStraight = getAutoSource()->getGCell()->isGoStraight(); - bool targetGoStraight = getAutoTarget()->getGCell()->isGoStraight(); + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); + + Interval sourceSide = source->getGCell()->getSide( Flags::Vertical ); + Interval targetSide = target->getGCell()->getSide( Flags::Vertical ); + Interval sourceConstraints = Interval(source->getCBYMin(),source->getCBYMax()); + Interval targetConstraints = Interval(target->getCBYMin(),target->getCBYMax()); + bool sourceGoStraight = source->getGCell()->isGoStraight(); + bool targetGoStraight = target->getGCell()->isGoStraight(); // Expand by a tiny amount for the "contains" to work for sure. sourceConstraints.inflate( 1 ); targetConstraints.inflate( 1 ); - cdebug_log(149,0) << "source " << getAutoSource() << endl; + cdebug_log(149,0) << "source " << source << endl; cdebug_log(149,0) << "source constraints: " << sourceConstraints << " " << DbU::getValueString(sourceConstraints.getSize()) << endl; - cdebug_log(149,0) << "target " << getAutoTarget() << endl; + cdebug_log(149,0) << "target " << target << endl; cdebug_log(149,0) << "target constraints: " << targetConstraints << " " << DbU::getValueString(targetConstraints.getSize()) << endl; if (not sourceGoStraight and not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; } if (not targetGoStraight and not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; } + if (not isUnbreakable()) { + if (source->isTurn() and (source->getPerpandicular(this)->getLayer() == getLayer())) { cdebug_tabw(149,-1); return true; } + if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) { cdebug_tabw(149,-1); return true; } + } + cdebug_tabw(149,-1); return false; } @@ -280,24 +288,35 @@ namespace Anabatic { const Configuration* configuration = Session::getConfiguration(); const Layer* metal2 = configuration->getRoutingLayer( 1 ); - bool success = false; - bool isMetal2Source = false; - bool isMetal2Target = false; - DbU::Unit height = 0; - AutoContact* source = getAutoSource(); - AutoContact* target = getAutoTarget(); + bool success = false; + bool isMetal2Source = false; + bool isMetal2Target = false; + bool isNonPrefSource = false; + bool isNonPrefTarget = false; + DbU::Unit height = 0; + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); + bool slackenSource = false; + bool slackenTarget = false; + + if (source->isTerminal()) { height = (static_cast(source->getAnchor()))->getBoundingBox().getHeight(); isMetal2Source = (source->getLayer() == metal2); + slackenSource = true; } if (target->isTerminal()) { height = std::min( height, (static_cast(target->getAnchor()))->getBoundingBox().getHeight() ); isMetal2Target = (target->getLayer() == metal2); + slackenTarget = true; } - - if (height >= 4*getPitch()) { - if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch())) - return false; + if (source->isTurn() and (source->getPerpandicular(this)->getLayer() == getLayer())) { + isNonPrefSource = true; + slackenSource = true; + } + if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) { + isNonPrefTarget = true; + slackenTarget = true; } cdebug_tabw(149,1); @@ -305,6 +324,14 @@ namespace Anabatic { cdebug_log(149,0) << "test:" << (getLength() < 5*getPitch()) << endl; cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl; + if (height >= 4*getPitch()) { + if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch())) { + cdebug_log(149,0) << "Too short terminal segment to slacken." << endl; + cdebug_tabw(149,-1); + return false; + } + } + int lowSlack = (flags & Flags::HalfSlacken) ? 3 : 10; bool sourceSlackened = false; bool targetSlackened = false; @@ -312,7 +339,7 @@ namespace Anabatic { DbU::Unit targetPosition = getTargetPosition(); AutoSegment* parallel = this; - if (source->isTerminal()) { + if (slackenSource) { Interval perpandConstraints = getAutoTarget()->getUConstraints(Flags::Horizontal); Interval constraints = source->getUConstraints (Flags::Vertical|Flags::NoGCellShrink); Interval nativeConstraints = source->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink); @@ -324,7 +351,7 @@ namespace Anabatic { << " native slack:" << nativeSlack << endl; cdebug_log(149,0) << "Perpand constraints on target: " << perpandConstraints << endl; // Ugly: GCell's track number is hardwired. - if ((nativeSlack < lowSlack) or (nativeSlack - slack < 3)) { + if (isNonPrefSource or (nativeSlack < lowSlack) or (nativeSlack - slack < 3)) { cdebug_log(149,0) << "Slackening from Source: " << source << endl; _makeDogleg( source->getGCell(), Flags::NoFlags ); sourceSlackened = true; @@ -352,7 +379,7 @@ namespace Anabatic { if (parallel) target = parallel->getAutoTarget(); - if (target->isTerminal()) { + if (slackenTarget) { Interval constraints = target->getUConstraints (Flags::Vertical|Flags::NoGCellShrink); Interval nativeConstraints = target->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink); int slack = constraints.getSize() / getPitch(); @@ -362,7 +389,7 @@ namespace Anabatic { cdebug_log(149,0) << "Target constraint: " << constraints << " slack:" << slack << " native slack:" << nativeSlack << endl; - if ((nativeSlack < lowSlack) or (nativeSlack - slack < 3)) { + if (isNonPrefTarget or (nativeSlack < lowSlack) or (nativeSlack - slack < 3)) { cdebug_log(149,0) << "Slackening from Target: " << target << endl; parallel->_makeDogleg( target->getGCell(), Flags::NoFlags ); targetSlackened = true; diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index d33cbad3..edc9d40d 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -1910,6 +1910,10 @@ namespace Anabatic { if (not getAutoTarget()->canMoveUp(this)) return false; return true; } + + // if (getAutoSource()->isTurn() and (getAutoSource()->getPerpandicular(this)->getLayer() == getLayer())) return false; + // if (getAutoTarget()->isTurn() and (getAutoTarget()->getPerpandicular(this)->getLayer() == getLayer())) return false; + cdebug_log(159,0) << "Both source & target Contacts can move up." << endl; //bool hasGlobalSegment = false; diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index 91fc52d6..31ab4a57 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -1192,7 +1192,10 @@ namespace Katana { } else { if (not _segment->canMoveUp(0.5,kflags)) return false; } - return _segment->moveUp( kflags|Flags::Propagate ); + + bool success = _segment->moveUp( kflags|Flags::Propagate ); + _fsm.addAction ( _segment, SegmentAction::OtherRipup ); + return success; } diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 4ee8a512..e2b89c3f 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -84,8 +84,22 @@ namespace { DataNegociate* data = segment->getDataNegociate(); if (not data) return; + TrackElement* refSegment = cost.getRefElement(); + DataNegociate* refData = refSegment->getDataNegociate(); + AutoSegment* refBase = refSegment->base(); + AutoSegment* base = segment->base(); + + if ( base and refBase and refData + and ( base->getRpDistance() == 0) + and (refBase->getRpDistance() > 0) + and (refData->getState() > DataNegociate::RipupPerpandiculars) + and ( data->getState() == DataNegociate::RipupPerpandiculars) + and ( data->getRipupCount() > 4)) { + cost.setAtRipupLimit(); + } + cost.mergeRipupCount( data->getRipupCount() ); - if ( segment->isLocal() ) { + if (segment->isLocal()) { cost.mergeDataState( data->getState() ); if (data->getState() >= DataNegociate::LocalVsGlobal) { cdebug_log(159,0) << "MaximumSlack/LocalVsGlobal for " << segment << endl; @@ -235,7 +249,7 @@ namespace Katana { , _segments () , _eventQueue () , _eventHistory() - , _eventLoop (10,50) + , _eventLoop (10,70) { } diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 8adae5ec..0ff017da 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -21,6 +21,8 @@ #include #include "vlsisapd/configuration/Configuration.h" #include "hurricane/Bug.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/UpdateSession.h" #include "hurricane/DebugSession.h" #include "hurricane/Breakpoint.h" #include "hurricane/Net.h" @@ -50,10 +52,12 @@ namespace Katana { using std::min; using std::ostringstream; using Hurricane::tab; + using Hurricane::Breakpoint; using Hurricane::DebugSession; using Hurricane::Bug; using Hurricane::Error; using Hurricane::BaseFlags; + using Hurricane::UpdateSession; using Hurricane::ForEachIterator; using Hurricane::Net; using Hurricane::Layer; @@ -446,7 +450,7 @@ namespace Katana { << " ripup:" << _segment->getDataNegociate()->getRipupCount() << endl; cdebug_log(159,0) << "Level: " << getEventLevel() - << ", area: " << _segment->getFreedomDegree() << endl; + << ", p-slack: " << _segment->getFreedomDegree() << endl; //_preCheck( _segment ); _eventLevel = 0; @@ -474,6 +478,13 @@ namespace Katana { cdebug_tabw(159,-1); queue.repushInvalidateds(); + + // if (getProcesseds() == 286892 + 1) { + // UpdateSession::close(); + // Breakpoint::stop( 1, "Stopping before revalidating event 286892." ); + // UpdateSession::open(); + // } + Session::revalidate(); queue.commit(); diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index e4ddcde6..de1c6687 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -1215,7 +1215,13 @@ namespace Katana { case DataNegociate::Dogleg: case DataNegociate::Slacken: if ((success = manipulator.slacken(Flags::HalfSlacken))) { + nextState = DataNegociate::LocalVsGlobal; + break; + } + case DataNegociate::LocalVsGlobal: + if (segment->isUnbreakable()) { nextState = DataNegociate::MaximumSlack; + success = true; break; } case DataNegociate::ConflictSolveByHistory: diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index a6b2e584..f25bf3bf 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -335,7 +335,8 @@ namespace Katana { cost.incDeltaShared ( overlap.getSize() ); } _segments[begin]->incOverlapCost( cost ); - cdebug_log(155,0) << "| overlap: " << _segments[begin] << " cost:" << &cost << endl; + cdebug_log(155,0) << "| overlap: " << _segments[begin] << endl; + cdebug_log(155,0) << "| current cost:" << &cost << endl; if (cost.isInfinite()) break; } diff --git a/katana/src/TrackCost.cpp b/katana/src/TrackCost.cpp index f3e4613d..79bd51ee 100644 --- a/katana/src/TrackCost.cpp +++ b/katana/src/TrackCost.cpp @@ -266,8 +266,8 @@ namespace Katana { s += string ( (isAtRipupLimit ())?"R":"-" ); s += string ( (isAnalog ())?"a":"-" ); s += string ( (isShortNet ())?"N":"-" ); - s += " " + getString(_terminals); - s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta); + s += " t:" + getString(_terminals); + s += "/d:" + /*DbU::getValueString(_delta)*/ getString(_delta); s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared); s += "/aw:" + DbU::getValueString(_axisWeight); s += "/dp:" + DbU::getValueString(_deltaPerpand); diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 4a18f2fe..d7662016 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -616,6 +616,7 @@ namespace Katana { bool TrackSegment::canSlacken () const { cdebug_log(159,0) << "TrackSegment::canSlacken() doglegLevel:" << getDoglegLevel() << endl; + if (isNonPref()) return false; return (not isSlackened() and (getDoglegLevel() <= 3)) ? _base->canSlacken(Flags::Propagate) : false; } diff --git a/katana/src/katana/TrackCost.h b/katana/src/katana/TrackCost.h index 5af8ae29..c2fc2bca 100644 --- a/katana/src/katana/TrackCost.h +++ b/katana/src/katana/TrackCost.h @@ -239,14 +239,14 @@ namespace Katana { inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; } inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; } inline void TrackCost::setAtRipupLimit () { _flags |= AtRipupLimit; } - inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } - inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } - inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } - inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; } - inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; } - inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); } - inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); } - inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); } + inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } + inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } + inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } + inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; } + inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; } + inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); } + inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); } + inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); } inline string TrackCost::_getTypeName () const { return "TrackCost"; }