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);
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<RoutingPad*>(source->getAnchor()))->getBoundingBox().getHeight();
isMetal2Source = (source->getLayer() == metal2);
slackenSource = true;
}
if (target->isTerminal()) {
height = std::min( height, (static_cast<RoutingPad*>(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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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)
{ }

View File

@ -21,6 +21,8 @@
#include <algorithm>
#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();

View File

@ -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:

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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"; }