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:
parent
1124e92ac2
commit
02eb5c56ad
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
{ }
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"; }
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue