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.
This commit is contained in:
Jean-Paul Chaput 2019-08-23 15:43:13 +02:00
parent 1124e92ac2
commit 02eb5c56ad
10 changed files with 104 additions and 37 deletions

View File

@ -245,27 +245,35 @@ namespace Anabatic {
{ {
cdebug_tabw(149,1); cdebug_tabw(149,1);
Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Vertical ); AutoContact* source = getAutoSource();
Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Vertical ); AutoContact* target = getAutoTarget();
Interval sourceConstraints = Interval(getAutoSource()->getCBYMin(),getAutoSource()->getCBYMax());
Interval targetConstraints = Interval(getAutoTarget()->getCBYMin(),getAutoTarget()->getCBYMax()); Interval sourceSide = source->getGCell()->getSide( Flags::Vertical );
bool sourceGoStraight = getAutoSource()->getGCell()->isGoStraight(); Interval targetSide = target->getGCell()->getSide( Flags::Vertical );
bool targetGoStraight = getAutoTarget()->getGCell()->isGoStraight(); 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. // Expand by a tiny amount for the "contains" to work for sure.
sourceConstraints.inflate( 1 ); sourceConstraints.inflate( 1 );
targetConstraints.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 cdebug_log(149,0) << "source constraints: " << sourceConstraints
<< " " << DbU::getValueString(sourceConstraints.getSize()) << endl; << " " << 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 cdebug_log(149,0) << "target constraints: " << targetConstraints
<< " " << DbU::getValueString(targetConstraints.getSize()) << endl; << " " << DbU::getValueString(targetConstraints.getSize()) << endl;
if (not sourceGoStraight and not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; } 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 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); cdebug_tabw(149,-1);
return false; return false;
} }
@ -283,21 +291,32 @@ namespace Anabatic {
bool success = false; bool success = false;
bool isMetal2Source = false; bool isMetal2Source = false;
bool isMetal2Target = false; bool isMetal2Target = false;
bool isNonPrefSource = false;
bool isNonPrefTarget = false;
DbU::Unit height = 0; DbU::Unit height = 0;
AutoContact* source = getAutoSource(); AutoContact* source = getAutoSource();
AutoContact* target = getAutoTarget(); AutoContact* target = getAutoTarget();
bool slackenSource = false;
bool slackenTarget = false;
if (source->isTerminal()) { if (source->isTerminal()) {
height = (static_cast<RoutingPad*>(source->getAnchor()))->getBoundingBox().getHeight(); height = (static_cast<RoutingPad*>(source->getAnchor()))->getBoundingBox().getHeight();
isMetal2Source = (source->getLayer() == metal2); isMetal2Source = (source->getLayer() == metal2);
slackenSource = true;
} }
if (target->isTerminal()) { if (target->isTerminal()) {
height = std::min( height, (static_cast<RoutingPad*>(target->getAnchor()))->getBoundingBox().getHeight() ); height = std::min( height, (static_cast<RoutingPad*>(target->getAnchor()))->getBoundingBox().getHeight() );
isMetal2Target = (target->getLayer() == metal2); isMetal2Target = (target->getLayer() == metal2);
slackenTarget = true;
} }
if (source->isTurn() and (source->getPerpandicular(this)->getLayer() == getLayer())) {
if (height >= 4*getPitch()) { isNonPrefSource = true;
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch())) slackenSource = true;
return false; }
if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) {
isNonPrefTarget = true;
slackenTarget = true;
} }
cdebug_tabw(149,1); cdebug_tabw(149,1);
@ -305,6 +324,14 @@ namespace Anabatic {
cdebug_log(149,0) << "test:" << (getLength() < 5*getPitch()) << endl; cdebug_log(149,0) << "test:" << (getLength() < 5*getPitch()) << endl;
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << 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; int lowSlack = (flags & Flags::HalfSlacken) ? 3 : 10;
bool sourceSlackened = false; bool sourceSlackened = false;
bool targetSlackened = false; bool targetSlackened = false;
@ -312,7 +339,7 @@ namespace Anabatic {
DbU::Unit targetPosition = getTargetPosition(); DbU::Unit targetPosition = getTargetPosition();
AutoSegment* parallel = this; AutoSegment* parallel = this;
if (source->isTerminal()) { if (slackenSource) {
Interval perpandConstraints = getAutoTarget()->getUConstraints(Flags::Horizontal); Interval perpandConstraints = getAutoTarget()->getUConstraints(Flags::Horizontal);
Interval constraints = source->getUConstraints (Flags::Vertical|Flags::NoGCellShrink); Interval constraints = source->getUConstraints (Flags::Vertical|Flags::NoGCellShrink);
Interval nativeConstraints = source->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink); Interval nativeConstraints = source->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink);
@ -324,7 +351,7 @@ namespace Anabatic {
<< " native slack:" << nativeSlack << endl; << " native slack:" << nativeSlack << endl;
cdebug_log(149,0) << "Perpand constraints on target: " << perpandConstraints << endl; cdebug_log(149,0) << "Perpand constraints on target: " << perpandConstraints << endl;
// Ugly: GCell's track number is hardwired. // 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; cdebug_log(149,0) << "Slackening from Source: " << source << endl;
_makeDogleg( source->getGCell(), Flags::NoFlags ); _makeDogleg( source->getGCell(), Flags::NoFlags );
sourceSlackened = true; sourceSlackened = true;
@ -352,7 +379,7 @@ namespace Anabatic {
if (parallel) target = parallel->getAutoTarget(); if (parallel) target = parallel->getAutoTarget();
if (target->isTerminal()) { if (slackenTarget) {
Interval constraints = target->getUConstraints (Flags::Vertical|Flags::NoGCellShrink); Interval constraints = target->getUConstraints (Flags::Vertical|Flags::NoGCellShrink);
Interval nativeConstraints = target->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink); Interval nativeConstraints = target->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink);
int slack = constraints.getSize() / getPitch(); int slack = constraints.getSize() / getPitch();
@ -362,7 +389,7 @@ namespace Anabatic {
cdebug_log(149,0) << "Target constraint: " << constraints cdebug_log(149,0) << "Target constraint: " << constraints
<< " slack:" << slack << " slack:" << slack
<< " native slack:" << nativeSlack << endl; << " 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; cdebug_log(149,0) << "Slackening from Target: " << target << endl;
parallel->_makeDogleg( target->getGCell(), Flags::NoFlags ); parallel->_makeDogleg( target->getGCell(), Flags::NoFlags );
targetSlackened = true; targetSlackened = true;

View File

@ -1910,6 +1910,10 @@ namespace Anabatic {
if (not getAutoTarget()->canMoveUp(this)) return false; if (not getAutoTarget()->canMoveUp(this)) return false;
return true; 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; cdebug_log(159,0) << "Both source & target Contacts can move up." << endl;
//bool hasGlobalSegment = false; //bool hasGlobalSegment = false;

View File

@ -1192,7 +1192,10 @@ namespace Katana {
} else { } else {
if (not _segment->canMoveUp(0.5,kflags)) return false; 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;
} }

View File

@ -84,8 +84,22 @@ namespace {
DataNegociate* data = segment->getDataNegociate(); DataNegociate* data = segment->getDataNegociate();
if (not data) return; 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() ); cost.mergeRipupCount( data->getRipupCount() );
if ( segment->isLocal() ) { if (segment->isLocal()) {
cost.mergeDataState( data->getState() ); cost.mergeDataState( data->getState() );
if (data->getState() >= DataNegociate::LocalVsGlobal) { if (data->getState() >= DataNegociate::LocalVsGlobal) {
cdebug_log(159,0) << "MaximumSlack/LocalVsGlobal for " << segment << endl; cdebug_log(159,0) << "MaximumSlack/LocalVsGlobal for " << segment << endl;
@ -235,7 +249,7 @@ namespace Katana {
, _segments () , _segments ()
, _eventQueue () , _eventQueue ()
, _eventHistory() , _eventHistory()
, _eventLoop (10,50) , _eventLoop (10,70)
{ } { }

View File

@ -21,6 +21,8 @@
#include <algorithm> #include <algorithm>
#include "vlsisapd/configuration/Configuration.h" #include "vlsisapd/configuration/Configuration.h"
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
#include "hurricane/Breakpoint.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
#include "hurricane/Breakpoint.h" #include "hurricane/Breakpoint.h"
#include "hurricane/Net.h" #include "hurricane/Net.h"
@ -50,10 +52,12 @@ namespace Katana {
using std::min; using std::min;
using std::ostringstream; using std::ostringstream;
using Hurricane::tab; using Hurricane::tab;
using Hurricane::Breakpoint;
using Hurricane::DebugSession; using Hurricane::DebugSession;
using Hurricane::Bug; using Hurricane::Bug;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::BaseFlags; using Hurricane::BaseFlags;
using Hurricane::UpdateSession;
using Hurricane::ForEachIterator; using Hurricane::ForEachIterator;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::Layer; using Hurricane::Layer;
@ -446,7 +450,7 @@ namespace Katana {
<< " ripup:" << _segment->getDataNegociate()->getRipupCount() << " ripup:" << _segment->getDataNegociate()->getRipupCount()
<< endl; << endl;
cdebug_log(159,0) << "Level: " << getEventLevel() cdebug_log(159,0) << "Level: " << getEventLevel()
<< ", area: " << _segment->getFreedomDegree() << endl; << ", p-slack: " << _segment->getFreedomDegree() << endl;
//_preCheck( _segment ); //_preCheck( _segment );
_eventLevel = 0; _eventLevel = 0;
@ -474,6 +478,13 @@ namespace Katana {
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
queue.repushInvalidateds(); queue.repushInvalidateds();
// if (getProcesseds() == 286892 + 1) {
// UpdateSession::close();
// Breakpoint::stop( 1, "Stopping before revalidating event 286892." );
// UpdateSession::open();
// }
Session::revalidate(); Session::revalidate();
queue.commit(); queue.commit();

View File

@ -1215,7 +1215,13 @@ namespace Katana {
case DataNegociate::Dogleg: case DataNegociate::Dogleg:
case DataNegociate::Slacken: case DataNegociate::Slacken:
if ((success = manipulator.slacken(Flags::HalfSlacken))) { if ((success = manipulator.slacken(Flags::HalfSlacken))) {
nextState = DataNegociate::LocalVsGlobal;
break;
}
case DataNegociate::LocalVsGlobal:
if (segment->isUnbreakable()) {
nextState = DataNegociate::MaximumSlack; nextState = DataNegociate::MaximumSlack;
success = true;
break; break;
} }
case DataNegociate::ConflictSolveByHistory: case DataNegociate::ConflictSolveByHistory:

View File

@ -335,7 +335,8 @@ namespace Katana {
cost.incDeltaShared ( overlap.getSize() ); cost.incDeltaShared ( overlap.getSize() );
} }
_segments[begin]->incOverlapCost( cost ); _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; if (cost.isInfinite()) break;
} }

View File

@ -266,8 +266,8 @@ namespace Katana {
s += string ( (isAtRipupLimit ())?"R":"-" ); s += string ( (isAtRipupLimit ())?"R":"-" );
s += string ( (isAnalog ())?"a":"-" ); s += string ( (isAnalog ())?"a":"-" );
s += string ( (isShortNet ())?"N":"-" ); s += string ( (isShortNet ())?"N":"-" );
s += " " + getString(_terminals); s += " t:" + getString(_terminals);
s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta); s += "/d:" + /*DbU::getValueString(_delta)*/ getString(_delta);
s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared); s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared);
s += "/aw:" + DbU::getValueString(_axisWeight); s += "/aw:" + DbU::getValueString(_axisWeight);
s += "/dp:" + DbU::getValueString(_deltaPerpand); s += "/dp:" + DbU::getValueString(_deltaPerpand);

View File

@ -616,6 +616,7 @@ namespace Katana {
bool TrackSegment::canSlacken () const bool TrackSegment::canSlacken () const
{ {
cdebug_log(159,0) << "TrackSegment::canSlacken() doglegLevel:" << getDoglegLevel() << endl; cdebug_log(159,0) << "TrackSegment::canSlacken() doglegLevel:" << getDoglegLevel() << endl;
if (isNonPref()) return false;
return (not isSlackened() and (getDoglegLevel() <= 3)) ? _base->canSlacken(Flags::Propagate) : false; return (not isSlackened() and (getDoglegLevel() <= 3)) ? _base->canSlacken(Flags::Propagate) : false;
} }