2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
2010-12-12 15:42:57 -06:00
|
|
|
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
|
2010-03-09 09:24:55 -06:00
|
|
|
//
|
|
|
|
// ===================================================================
|
|
|
|
//
|
|
|
|
// $Id$
|
|
|
|
//
|
|
|
|
// x-----------------------------------------------------------------x
|
|
|
|
// | |
|
|
|
|
// | C O R I O L I S |
|
|
|
|
// | K i t e - D e t a i l e d R o u t e r |
|
|
|
|
// | |
|
|
|
|
// | Author : Jean-Paul CHAPUT |
|
|
|
|
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
|
|
|
// | =============================================================== |
|
|
|
|
// | C++ Module : "./TrackSegment.cpp" |
|
|
|
|
// | *************************************************************** |
|
|
|
|
// | U p d a t e s |
|
|
|
|
// | |
|
|
|
|
// x-----------------------------------------------------------------x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <sstream>
|
2010-05-28 04:17:29 -05:00
|
|
|
#include <limits>
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
#include "hurricane/Bug.h"
|
|
|
|
#include "hurricane/Warning.h"
|
|
|
|
#include "hurricane/Net.h"
|
|
|
|
#include "hurricane/Name.h"
|
2010-04-12 06:24:57 -05:00
|
|
|
#include "hurricane/RoutingPad.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
#include "katabatic/AutoContact.h"
|
2010-12-12 15:42:57 -06:00
|
|
|
#include "katabatic/GCell.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
#include "crlcore/RoutingGauge.h"
|
|
|
|
#include "kite/DataNegociate.h"
|
|
|
|
#include "kite/TrackSegment.h"
|
|
|
|
#include "kite/Track.h"
|
|
|
|
#include "kite/Session.h"
|
|
|
|
#include "kite/RoutingEvent.h"
|
|
|
|
#include "kite/NegociateWindow.h"
|
|
|
|
#include "kite/KiteEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Kite {
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using Hurricane::inltrace;
|
|
|
|
using Hurricane::ltracein;
|
|
|
|
using Hurricane::ltraceout;
|
|
|
|
using Hurricane::tab;
|
|
|
|
using Hurricane::ForEachIterator;
|
|
|
|
using Hurricane::Bug;
|
|
|
|
using Hurricane::Error;
|
|
|
|
using Hurricane::Net;
|
|
|
|
using Hurricane::Name;
|
2010-04-12 06:24:57 -05:00
|
|
|
using Hurricane::RoutingPad;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "TrackSegment".
|
|
|
|
|
|
|
|
|
|
|
|
TrackSegment::TrackSegment ( AutoSegment* segment, Track* track )
|
|
|
|
: TrackElement (track)
|
|
|
|
, _base (segment)
|
|
|
|
, _created (true)
|
|
|
|
, _lock (true)
|
|
|
|
, _revalidated (false)
|
|
|
|
, _sourceDogLeg (false)
|
|
|
|
, _targetDogLeg (false)
|
|
|
|
, _canRipple (false)
|
|
|
|
, _routed (false)
|
|
|
|
, _area (0)
|
|
|
|
, _data (NULL)
|
|
|
|
, _dogLegLevel (0)
|
|
|
|
{
|
|
|
|
if (segment) {
|
|
|
|
_data = new DataNegociate ( this );
|
|
|
|
_base->getCanonical ( _sourceU, _targetU );
|
|
|
|
setArea ();
|
|
|
|
//update ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::_postCreate ()
|
|
|
|
{
|
|
|
|
TrackElement::_postCreate ();
|
|
|
|
Session::link ( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackSegment::~TrackSegment ()
|
2010-12-12 15:42:57 -06:00
|
|
|
{ if ( _data ) delete _data; }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::_preDestroy ()
|
|
|
|
{
|
|
|
|
ltrace(90) << "TrackSegment::_preDestroy() - " << (void*)this
|
|
|
|
<< " [" << (void*)_base << ", "
|
|
|
|
<< (void*)(_base?_base->base():NULL) << "]" << endl;
|
|
|
|
|
|
|
|
Session::unlink ( this );
|
|
|
|
|
|
|
|
TrackElement::_preDestroy ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::create ( AutoSegment* segment, Track* track, bool& created )
|
|
|
|
{
|
|
|
|
created = false;
|
|
|
|
|
|
|
|
TrackElement* trackElement = Session::lookup ( segment->base() );
|
2010-12-12 15:42:57 -06:00
|
|
|
if ( not trackElement ) {
|
2010-03-09 09:24:55 -06:00
|
|
|
TrackSegment* trackSegment = new TrackSegment ( segment, track );
|
|
|
|
trackSegment->_postCreate ();
|
|
|
|
created = true;
|
|
|
|
|
|
|
|
trackSegment->invalidate ();
|
|
|
|
|
|
|
|
ltrace(200) << "TrackSegment::create(): " << trackSegment << endl;
|
|
|
|
trackElement = trackSegment;
|
|
|
|
}
|
|
|
|
|
|
|
|
return trackElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Formerly Inline Functions.
|
|
|
|
AutoSegment* TrackSegment::base () const { return _base; }
|
* ./kite:
- New: In NegociateWindow/RoutingEvent, adds a more comprehensive stage
"Repair". Perform in three stage: first try to place with a relaxed
constraint (one GCell on each side). Second try to minimize the faulty
segment. Third perform another "repack perpandicular" but this time
the faulty segment is re-inserted *before* any of it's perpandiculars.
- New: In RoutingEvent::cacheAxisHint(), when a segment has a parent, that
is comes for a "moveUp()", uses the parent axis hint as it's own.
- New: In State::slackenTopology(), in the global FSM, adds a special
operation when reaching MaximumSlack: forceOverLocals(), try to insert
the global on track containing only local segments. Should tend to
concentrate locals on a small set of shared tracks. Most useful on the
highest layers.
- New: In State::slackenTopology(), in the "MoveUp" state, try to find the
more appropriate segment to move up (Manipulator::desaturate()).
Effectively move up the longest segment fully enclosing the one we are
processing.
- New: In State::slackenTopology(), add a check for fully blocked segments
in the local segment FSM. Calls State::solveFullBlocked().
- New: In KiteEngine::createGlobalGraph(), decrease the vertical capacity
of one track inside the core. Helps smooth the vertical density.
- Change: In Manipulator::insertInTrack(), when a track is freed for a
to be inserted changes the priorities so that the segment is immediatly
inserted. Parallels ripeds and theirs perpandiculars are replaced
only *after*. This is the opposite of the previous behavior.
- Change: In NegociateWindow::NegociateOverlapCost(), account the costs
of terminals only for deep depth layers (M1, M2 & M3).
- Change: In RoutingEvent::insertInTrack(), expand the excluded interval
by a half-pitch (2.5l) instead of one lambda.
- Change: In State::State(), do not uses DiscardGlobal if the ripup count
exceed 5. Case of the "Strap" segments that can be ripped a lot
before changing state.
- Change: In State::_processNegociate(), no longer lock into position
(fixed) the local terminal segments as a last resort.
- Change: In RoutingEvent::_processNegociate(), no longer ripup perpandiculars
when a segment is inserted in a free space. Reduce the number of
events whithout degrading the routing quality.
- Change: In State::conflictSolve1_v1b(), if getLongestConflict() is nul,
ignore the track, the conflict must occurs on another track.
- Change: In TrackCost, add a flag support. First uses, a flags to prevent
a local of the topmost layer to ripup a global which is in moveUp
state.
- Bug: In State::solveFullBlockage(), after have been freed, reset the
segment state to "moveUp".
- Bug: In manipulator::minimize(), the axisHint was miscalculated if the
punctual span was empty.
2011-01-25 11:16:50 -06:00
|
|
|
bool TrackSegment::isBipoint () const { return _base->isBipoint(); }
|
2010-03-09 09:24:55 -06:00
|
|
|
bool TrackSegment::isCreated () const { return _created; }
|
|
|
|
bool TrackSegment::isFixed () const { return _base->isFixed(); }
|
|
|
|
bool TrackSegment::isStrap () const { return _base->isCanonicalStrap(); }
|
|
|
|
bool TrackSegment::isSlackenStrap () const { return _base->isSlackenStrap(); }
|
|
|
|
bool TrackSegment::isLocal () const { return _base->isCanonicalLocal(); }
|
|
|
|
bool TrackSegment::isGlobal () const { return !isLocal(); }
|
|
|
|
bool TrackSegment::isLocked () const { return _lock; }
|
|
|
|
bool TrackSegment::isTerminal () const { return _base->isTerminal(); }
|
* ./kite:
- New: In NegociateWindow/RoutingEvent, adds a more comprehensive stage
"Repair". Perform in three stage: first try to place with a relaxed
constraint (one GCell on each side). Second try to minimize the faulty
segment. Third perform another "repack perpandicular" but this time
the faulty segment is re-inserted *before* any of it's perpandiculars.
- New: In RoutingEvent::cacheAxisHint(), when a segment has a parent, that
is comes for a "moveUp()", uses the parent axis hint as it's own.
- New: In State::slackenTopology(), in the global FSM, adds a special
operation when reaching MaximumSlack: forceOverLocals(), try to insert
the global on track containing only local segments. Should tend to
concentrate locals on a small set of shared tracks. Most useful on the
highest layers.
- New: In State::slackenTopology(), in the "MoveUp" state, try to find the
more appropriate segment to move up (Manipulator::desaturate()).
Effectively move up the longest segment fully enclosing the one we are
processing.
- New: In State::slackenTopology(), add a check for fully blocked segments
in the local segment FSM. Calls State::solveFullBlocked().
- New: In KiteEngine::createGlobalGraph(), decrease the vertical capacity
of one track inside the core. Helps smooth the vertical density.
- Change: In Manipulator::insertInTrack(), when a track is freed for a
to be inserted changes the priorities so that the segment is immediatly
inserted. Parallels ripeds and theirs perpandiculars are replaced
only *after*. This is the opposite of the previous behavior.
- Change: In NegociateWindow::NegociateOverlapCost(), account the costs
of terminals only for deep depth layers (M1, M2 & M3).
- Change: In RoutingEvent::insertInTrack(), expand the excluded interval
by a half-pitch (2.5l) instead of one lambda.
- Change: In State::State(), do not uses DiscardGlobal if the ripup count
exceed 5. Case of the "Strap" segments that can be ripped a lot
before changing state.
- Change: In State::_processNegociate(), no longer lock into position
(fixed) the local terminal segments as a last resort.
- Change: In RoutingEvent::_processNegociate(), no longer ripup perpandiculars
when a segment is inserted in a free space. Reduce the number of
events whithout degrading the routing quality.
- Change: In State::conflictSolve1_v1b(), if getLongestConflict() is nul,
ignore the track, the conflict must occurs on another track.
- Change: In TrackCost, add a flag support. First uses, a flags to prevent
a local of the topmost layer to ripup a global which is in moveUp
state.
- Bug: In State::solveFullBlockage(), after have been freed, reset the
segment state to "moveUp".
- Bug: In manipulator::minimize(), the axisHint was miscalculated if the
punctual span was empty.
2011-01-25 11:16:50 -06:00
|
|
|
bool TrackSegment::isDogleg () const { return _base->isDogleg(); }
|
2010-03-09 09:24:55 -06:00
|
|
|
bool TrackSegment::isRevalidated () const { return _revalidated; }
|
|
|
|
bool TrackSegment::isRouted () const { return _routed; }
|
|
|
|
bool TrackSegment::isSlackened () const { return _base->isSlackened(); }
|
|
|
|
bool TrackSegment::isSlackenDogLeg () const { return isSlackened() and (_dogLegLevel > 0); }
|
|
|
|
bool TrackSegment::hasSourceDogLeg () const { return _sourceDogLeg; }
|
|
|
|
bool TrackSegment::hasTargetDogLeg () const { return _targetDogLeg; }
|
|
|
|
bool TrackSegment::allowOutsideGCell () const { return _base->allowOutsideGCell(); }
|
|
|
|
bool TrackSegment::canGoOutsideGCell () const { return _base->canGoOutsideGCell(); }
|
|
|
|
bool TrackSegment::canRipple () const { return _canRipple; }
|
|
|
|
unsigned long TrackSegment::getId () const { return _base->getId(); }
|
|
|
|
DbU::Unit TrackSegment::getAxis () const { return _base->getAxis(); }
|
|
|
|
unsigned long TrackSegment::getArea () const { return _area; }
|
|
|
|
unsigned int TrackSegment::getDogLegLevel () const { return _dogLegLevel; }
|
|
|
|
Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); }
|
|
|
|
Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); }
|
|
|
|
TrackElements TrackSegment::getCollapsedPerpandiculars () { return new TrackElements_CollapsedPerpandicular(this); }
|
|
|
|
void TrackSegment::setAllowOutsideGCell ( bool state ) { _base->setAllowOutsideGCell(state,true); }
|
|
|
|
void TrackSegment::setLock ( bool state ) { _lock = state; }
|
|
|
|
void TrackSegment::setRevalidated ( bool state ) { _revalidated = state; }
|
|
|
|
void TrackSegment::invalidate () { _base->invalidate(); }
|
|
|
|
void TrackSegment::setCanRipple ( bool state ) { _canRipple = state; }
|
|
|
|
void TrackSegment::setSourceDogLeg ( bool state ) { _sourceDogLeg = state; }
|
|
|
|
void TrackSegment::setTargetDogLeg ( bool state ) { _targetDogLeg = state; }
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::getCanonical ( Interval& i )
|
|
|
|
{ return Session::lookup ( _base->getCanonical(i)->base() ); }
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::canSlacken () const
|
|
|
|
{ return (not isSlackened())?(_base->canSlacken(true)):false; }
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::isHorizontal () const
|
|
|
|
{ return _base->isHorizontal(); }
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::isVertical () const
|
|
|
|
{ return _base->isVertical(); }
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int TrackSegment::getDirection () const
|
|
|
|
{ return _base->getDirection(); }
|
|
|
|
|
|
|
|
|
|
|
|
Net* TrackSegment::getNet () const
|
|
|
|
{ return _base->getNet(); }
|
|
|
|
|
|
|
|
|
|
|
|
const Layer* TrackSegment::getLayer () const
|
|
|
|
{ return _base->getLayer(); }
|
|
|
|
|
|
|
|
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
DataNegociate* TrackSegment::getDataNegociate ( unsigned int flags ) const
|
|
|
|
{
|
|
|
|
if ( flags & TrackElement::DataSelf ) return _data;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
TrackElement* parent = getParent();
|
|
|
|
return (parent) ? parent->getDataNegociate() : NULL;
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::getNext () const
|
|
|
|
{
|
|
|
|
size_t dummy = _index;
|
|
|
|
return _track->getNext ( dummy, getNet() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::getPrevious () const
|
|
|
|
{
|
|
|
|
size_t dummy = _index;
|
|
|
|
return _track->getPrevious ( dummy, getNet() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
TrackElement* TrackSegment::getParent () const
|
|
|
|
{
|
|
|
|
AutoSegment* baseParent = base()->getParent();
|
|
|
|
if ( not baseParent ) return NULL;
|
|
|
|
|
|
|
|
TrackElement* element = Session::lookup ( baseParent );
|
|
|
|
return element;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
Interval TrackSegment::getFreeInterval () const
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
if ( not _track ) return Interval(false);
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
size_t begin = _index;
|
|
|
|
size_t end = _index;
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
return _track->expandFreeInterval ( begin, end, Track::Inside, getNet() );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
size_t TrackSegment::getGCells ( vector<Katabatic::GCell*>& gcells ) const
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
vector<Katabatic::GCell*>().swap ( gcells );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
Katabatic::GCell* sourceGCell = base()->getAutoSource()->getGCell();
|
|
|
|
Katabatic::GCell* targetGCell = base()->getAutoTarget()->getGCell();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltrace(148) << "getGCells(): sourceGCell: " << sourceGCell << endl;
|
|
|
|
ltrace(148) << "getGCells(): targetGCell: " << targetGCell << endl;
|
|
|
|
|
|
|
|
forEach ( AutoSegment*, isegment, base()->getCollapseds() ) {
|
2010-12-12 15:42:57 -06:00
|
|
|
Katabatic::GCell* gcell = isegment->getAutoSource()->getGCell();
|
2010-03-09 09:24:55 -06:00
|
|
|
if ( gcell->getIndex() < sourceGCell->getIndex() ) {
|
|
|
|
sourceGCell = gcell;
|
|
|
|
ltrace(148) << "getGCells(): new sourceGCell: " << sourceGCell << endl;
|
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
gcell = isegment->getAutoTarget()->getGCell();
|
2010-03-09 09:24:55 -06:00
|
|
|
if ( gcell->getIndex() > targetGCell->getIndex() ) {
|
|
|
|
targetGCell = gcell;
|
|
|
|
ltrace(148) << "getGCells(): new targetGCell: " << targetGCell << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( not sourceGCell or not targetGCell ) return 0;
|
|
|
|
if ( not sourceGCell ) { gcells.push_back ( targetGCell ); return 1; }
|
|
|
|
if ( not targetGCell ) { gcells.push_back ( sourceGCell ); return 1; }
|
|
|
|
|
|
|
|
if ( isHorizontal() ) {
|
|
|
|
gcells.push_back ( sourceGCell );
|
|
|
|
while ( sourceGCell != targetGCell ) {
|
|
|
|
sourceGCell = sourceGCell->getRight();
|
|
|
|
if ( not sourceGCell ) break;
|
|
|
|
|
|
|
|
//cerr << " Pushing: " << sourceGCell << endl;
|
|
|
|
gcells.push_back ( sourceGCell );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
gcells.push_back ( sourceGCell );
|
|
|
|
while ( sourceGCell != targetGCell ) {
|
|
|
|
sourceGCell = sourceGCell->getUp();
|
|
|
|
if ( not sourceGCell ) break;
|
|
|
|
|
|
|
|
gcells.push_back ( sourceGCell );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return gcells.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t TrackSegment::getPerpandicularsBound ( set<TrackElement*>& bounds )
|
|
|
|
{
|
|
|
|
bounds.clear ();
|
|
|
|
|
|
|
|
set<AutoSegment*> baseBounds;
|
|
|
|
set<AutoSegment*>::iterator ibase;
|
|
|
|
_base->getPerpandicularsBound ( baseBounds );
|
|
|
|
|
|
|
|
for ( ibase = baseBounds.begin() ; ibase != baseBounds.end() ; ibase++ ) {
|
|
|
|
TrackElement* segment = Session::lookup ( *ibase );
|
|
|
|
if ( segment )
|
|
|
|
bounds.insert ( segment );
|
|
|
|
}
|
|
|
|
|
|
|
|
return bounds.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::setDogLegLevel ( unsigned int level )
|
|
|
|
{
|
|
|
|
if ( level > 15 ) {
|
|
|
|
cerr << Bug("%s has reached maximum dog leg count (15)."
|
|
|
|
,_getString().c_str()) << endl;
|
|
|
|
level = 15;
|
|
|
|
}
|
|
|
|
|
|
|
|
_dogLegLevel = level;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::dataInvalidate ()
|
|
|
|
{ if (_data) _data->invalidate(); }
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::eventInvalidate ()
|
|
|
|
{
|
|
|
|
if ( !_data ) return;
|
|
|
|
|
|
|
|
RoutingEvent* event = _data->getRoutingEvent();
|
|
|
|
if ( event ) event->invalidate ( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::setArea ()
|
|
|
|
{
|
|
|
|
//float length = getValue ( getTargetU() - getSourceU() );
|
|
|
|
//float height = getValue ( getSlack() );
|
|
|
|
//_area = (unsigned long)( length * height );
|
|
|
|
_area = _base->getSlack();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::setRouted ( bool state )
|
|
|
|
{ _routed = state; }
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::setTrack ( Track* track )
|
2010-12-12 15:42:57 -06:00
|
|
|
{ TrackElement::setTrack ( track ); }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::detach ()
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::detach() - <id:" << getId() << ">" << endl;
|
|
|
|
|
|
|
|
setTrack ( NULL );
|
|
|
|
setIndex ( (size_t)-1 );
|
|
|
|
setLock ( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::revalidate ( bool invalidEvent )
|
|
|
|
{
|
|
|
|
_created = false;
|
|
|
|
ltrace(148) << "revalidate() - " << this << endl;
|
|
|
|
|
|
|
|
_base->getCanonical ( _sourceU, _targetU );
|
|
|
|
_data->update ();
|
|
|
|
if ( invalidEvent )
|
|
|
|
_data->invalidate ( true, true );
|
|
|
|
|
|
|
|
if ( _track ) Session::addSortEvent ( _track );
|
|
|
|
_revalidated = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::setAxis ( DbU::Unit axis, unsigned int flags )
|
|
|
|
{
|
|
|
|
_base->setAxis ( axis, flags );
|
|
|
|
invalidate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::swapTrack ( TrackElement* other )
|
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
if ( not other ) return;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltrace(200) << "TrackSegment::swapTrack()" << endl;
|
|
|
|
|
|
|
|
size_t thisIndex = getIndex ();
|
|
|
|
Track* thisTrack = getTrack ();
|
|
|
|
size_t otherIndex = other->getIndex ();
|
|
|
|
Track* otherTrack = other->getTrack ();
|
|
|
|
|
|
|
|
if ( _track and otherTrack and (_track != otherTrack) ) {
|
|
|
|
cerr << Error("TrackSegment::swapTrack() - swapping TrackSement from different tracks.") << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// detach ();
|
|
|
|
// other->detach ();
|
|
|
|
// if ( thisTrack ) thisTrack ->insert ( other );
|
|
|
|
// if ( otherTrack ) otherTrack->insert ( this );
|
|
|
|
|
|
|
|
setTrack ( NULL );
|
|
|
|
other->setTrack ( NULL );
|
|
|
|
|
|
|
|
//other->setRouted ( thisRouted );
|
|
|
|
other->setTrack ( thisTrack );
|
|
|
|
other->setIndex ( thisIndex );
|
|
|
|
if ( thisTrack ) thisTrack->setSegment ( other, thisIndex );
|
|
|
|
|
|
|
|
//setRouted ( otherRouted );
|
|
|
|
setTrack ( otherTrack );
|
|
|
|
setIndex ( otherIndex );
|
|
|
|
if ( _track ) _track->setSegment ( this, _index );
|
|
|
|
|
|
|
|
#if defined(CHECK_DATABASE_DISABLED)
|
|
|
|
if ( _track )
|
|
|
|
_track->_check();
|
|
|
|
else if ( other->getTrack() )
|
|
|
|
other->getTrack()->_check();
|
|
|
|
#endif
|
|
|
|
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
RoutingEvent* thisEvent = getDataNegociate(TrackElement::DataSelf)->getRoutingEvent();
|
2010-03-09 09:24:55 -06:00
|
|
|
RoutingEvent* otherEvent = other->getDataNegociate()->getRoutingEvent();
|
|
|
|
|
|
|
|
if ( thisEvent ) thisEvent ->setSegment ( other );
|
|
|
|
if ( otherEvent ) otherEvent->setSegment ( this );
|
|
|
|
|
|
|
|
ltrace(200) << "| this: " << this << endl;
|
|
|
|
ltrace(200) << "| other: " << other << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::reschedule ( unsigned int level )
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::reschedule() - " << this << endl;
|
|
|
|
ltracein(200);
|
2010-04-12 06:24:57 -05:00
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
if ( not _data or not _data->hasRoutingEvent() )
|
|
|
|
Session::getNegociateWindow()->addInsertEvent ( this, level );
|
|
|
|
else {
|
|
|
|
if ( _track != NULL )
|
|
|
|
Session::addRemoveEvent ( this );
|
|
|
|
Session::getNegociateWindow()->rescheduleEvent ( _data->getRoutingEvent(), level );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
2010-12-12 15:42:57 -06:00
|
|
|
|
2010-03-09 09:24:55 -06:00
|
|
|
ltraceout(200);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::slacken ()
|
|
|
|
{
|
|
|
|
if ( not isSlackened() ) {
|
|
|
|
ltrace(200) << "TrackSegment::slacken()" << endl;
|
|
|
|
ltracein(200);
|
|
|
|
|
|
|
|
base()->slacken ( true );
|
|
|
|
_postModify ();
|
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
} else
|
|
|
|
throw Bug("TrackSegment::slacken(): NULL base or already slackened.");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* ./kite:
- New: In NegociateWindow/RoutingEvent, adds a more comprehensive stage
"Repair". Perform in three stage: first try to place with a relaxed
constraint (one GCell on each side). Second try to minimize the faulty
segment. Third perform another "repack perpandicular" but this time
the faulty segment is re-inserted *before* any of it's perpandiculars.
- New: In RoutingEvent::cacheAxisHint(), when a segment has a parent, that
is comes for a "moveUp()", uses the parent axis hint as it's own.
- New: In State::slackenTopology(), in the global FSM, adds a special
operation when reaching MaximumSlack: forceOverLocals(), try to insert
the global on track containing only local segments. Should tend to
concentrate locals on a small set of shared tracks. Most useful on the
highest layers.
- New: In State::slackenTopology(), in the "MoveUp" state, try to find the
more appropriate segment to move up (Manipulator::desaturate()).
Effectively move up the longest segment fully enclosing the one we are
processing.
- New: In State::slackenTopology(), add a check for fully blocked segments
in the local segment FSM. Calls State::solveFullBlocked().
- New: In KiteEngine::createGlobalGraph(), decrease the vertical capacity
of one track inside the core. Helps smooth the vertical density.
- Change: In Manipulator::insertInTrack(), when a track is freed for a
to be inserted changes the priorities so that the segment is immediatly
inserted. Parallels ripeds and theirs perpandiculars are replaced
only *after*. This is the opposite of the previous behavior.
- Change: In NegociateWindow::NegociateOverlapCost(), account the costs
of terminals only for deep depth layers (M1, M2 & M3).
- Change: In RoutingEvent::insertInTrack(), expand the excluded interval
by a half-pitch (2.5l) instead of one lambda.
- Change: In State::State(), do not uses DiscardGlobal if the ripup count
exceed 5. Case of the "Strap" segments that can be ripped a lot
before changing state.
- Change: In State::_processNegociate(), no longer lock into position
(fixed) the local terminal segments as a last resort.
- Change: In RoutingEvent::_processNegociate(), no longer ripup perpandiculars
when a segment is inserted in a free space. Reduce the number of
events whithout degrading the routing quality.
- Change: In State::conflictSolve1_v1b(), if getLongestConflict() is nul,
ignore the track, the conflict must occurs on another track.
- Change: In TrackCost, add a flag support. First uses, a flags to prevent
a local of the topmost layer to ripup a global which is in moveUp
state.
- Bug: In State::solveFullBlockage(), after have been freed, reset the
segment state to "moveUp".
- Bug: In manipulator::minimize(), the axisHint was miscalculated if the
punctual span was empty.
2011-01-25 11:16:50 -06:00
|
|
|
float TrackSegment::getMaxUnderDensity ( unsigned int flags ) const
|
|
|
|
{ return _base->getMaxUnderDensity ( flags ); }
|
|
|
|
|
|
|
|
|
2010-04-23 08:14:17 -05:00
|
|
|
bool TrackSegment::canPivotUp ( float reserve ) const
|
2010-12-12 15:42:57 -06:00
|
|
|
{ return _base->canPivotUp(reserve); }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
bool TrackSegment::canPivotDown ( float reserve ) const
|
|
|
|
{ return _base->canPivotDown(reserve); }
|
|
|
|
|
|
|
|
|
* ./kite:
- Change: Propagate renaming "obstacle" -> "blockage".
- Bug/Change: In Configuration, the value of the extensionCap was too big
(1.5 lambda), reduce to 0.5 lambda. This is a problem, the extension
should be coupled to the layer as it is not the same for each METAL.
- Bug: When using TrackElement, always uses the virtual "->isFixed()" method
instead of trying to access to "->base()->isFixed()" as the base may be
NULL in case of blockage/fixed segment.
- Change: Merge PowerRails & Blockage trans-hierarchical construction (into
PowerRails). All blockages are groupeds under "blockagenet".
Allows to remove TrackBlockage & BuildBlockages.
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
ring power segments around the core must completly saturate the edges
in their segment direction. This is to prevent the global router to
use paths under the power/ground ring (may generate unsolvable configs).
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
distinguish three areas: the core (65%), the corona (90%) and the pads
(100%). Capacities on the edges are sets accordingly.
- Change: In RoutingEvent, introduce an alternative algorithm for
conflictSolve1, FindPath which try to deduce the breakpoints from a
truly explorated path. Unfortunatly this gives worst results than the
Cs1Candidates method. The why should be investigated as it's a critical
point in the algorithm.
- Change: In Manipulator::ripupPerpandicular(), when a caged perpandicular
is encountered, instead of just "stopping", rip it up and change is
axis hint (actually increase) it's axis hint so it stands a chance to
go outside the track with an obstacle.
- Change: In RoutingEvent/State::slackenTopology(), allow move up of local
segments when they are tightly constrained *and* blocked (cageds).
Partial modification of functions calls from booleans to flags.
- Bug: In NegociateWindow::NegociateOverlapCost, check for fixed segments
before trying to get DataNegociate. The lack of DataNegociate cause the
TrackElement to be discarted. It's a failsafe behavior, but it leads to
overlaps.
- Bug: In ProtectRoutingPad, in Pad Cells only, *do not* protect RoutingPad
to avoid the edge capacity over the pad to decrease to zero. This is
due to unused RoutingPads being accounted as blockages.
2010-12-04 09:25:48 -06:00
|
|
|
bool TrackSegment::canMoveUp ( float reserve, unsigned int flags ) const
|
2010-12-12 15:42:57 -06:00
|
|
|
{ return _base->canMoveUp ( reserve, flags ); }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
* ./kite:
- Change: Propagate renaming "obstacle" -> "blockage".
- Bug/Change: In Configuration, the value of the extensionCap was too big
(1.5 lambda), reduce to 0.5 lambda. This is a problem, the extension
should be coupled to the layer as it is not the same for each METAL.
- Bug: When using TrackElement, always uses the virtual "->isFixed()" method
instead of trying to access to "->base()->isFixed()" as the base may be
NULL in case of blockage/fixed segment.
- Change: Merge PowerRails & Blockage trans-hierarchical construction (into
PowerRails). All blockages are groupeds under "blockagenet".
Allows to remove TrackBlockage & BuildBlockages.
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
ring power segments around the core must completly saturate the edges
in their segment direction. This is to prevent the global router to
use paths under the power/ground ring (may generate unsolvable configs).
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
distinguish three areas: the core (65%), the corona (90%) and the pads
(100%). Capacities on the edges are sets accordingly.
- Change: In RoutingEvent, introduce an alternative algorithm for
conflictSolve1, FindPath which try to deduce the breakpoints from a
truly explorated path. Unfortunatly this gives worst results than the
Cs1Candidates method. The why should be investigated as it's a critical
point in the algorithm.
- Change: In Manipulator::ripupPerpandicular(), when a caged perpandicular
is encountered, instead of just "stopping", rip it up and change is
axis hint (actually increase) it's axis hint so it stands a chance to
go outside the track with an obstacle.
- Change: In RoutingEvent/State::slackenTopology(), allow move up of local
segments when they are tightly constrained *and* blocked (cageds).
Partial modification of functions calls from booleans to flags.
- Bug: In NegociateWindow::NegociateOverlapCost, check for fixed segments
before trying to get DataNegociate. The lack of DataNegociate cause the
TrackElement to be discarted. It's a failsafe behavior, but it leads to
overlaps.
- Bug: In ProtectRoutingPad, in Pad Cells only, *do not* protect RoutingPad
to avoid the edge capacity over the pad to decrease to zero. This is
due to unused RoutingPads being accounted as blockages.
2010-12-04 09:25:48 -06:00
|
|
|
bool TrackSegment::moveUp ( unsigned int flags )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
|
* ./kite:
- Change: Propagate renaming "obstacle" -> "blockage".
- Bug/Change: In Configuration, the value of the extensionCap was too big
(1.5 lambda), reduce to 0.5 lambda. This is a problem, the extension
should be coupled to the layer as it is not the same for each METAL.
- Bug: When using TrackElement, always uses the virtual "->isFixed()" method
instead of trying to access to "->base()->isFixed()" as the base may be
NULL in case of blockage/fixed segment.
- Change: Merge PowerRails & Blockage trans-hierarchical construction (into
PowerRails). All blockages are groupeds under "blockagenet".
Allows to remove TrackBlockage & BuildBlockages.
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
ring power segments around the core must completly saturate the edges
in their segment direction. This is to prevent the global router to
use paths under the power/ground ring (may generate unsolvable configs).
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
distinguish three areas: the core (65%), the corona (90%) and the pads
(100%). Capacities on the edges are sets accordingly.
- Change: In RoutingEvent, introduce an alternative algorithm for
conflictSolve1, FindPath which try to deduce the breakpoints from a
truly explorated path. Unfortunatly this gives worst results than the
Cs1Candidates method. The why should be investigated as it's a critical
point in the algorithm.
- Change: In Manipulator::ripupPerpandicular(), when a caged perpandicular
is encountered, instead of just "stopping", rip it up and change is
axis hint (actually increase) it's axis hint so it stands a chance to
go outside the track with an obstacle.
- Change: In RoutingEvent/State::slackenTopology(), allow move up of local
segments when they are tightly constrained *and* blocked (cageds).
Partial modification of functions calls from booleans to flags.
- Bug: In NegociateWindow::NegociateOverlapCost, check for fixed segments
before trying to get DataNegociate. The lack of DataNegociate cause the
TrackElement to be discarted. It's a failsafe behavior, but it leads to
overlaps.
- Bug: In ProtectRoutingPad, in Pad Cells only, *do not* protect RoutingPad
to avoid the edge capacity over the pad to decrease to zero. This is
due to unused RoutingPads being accounted as blockages.
2010-12-04 09:25:48 -06:00
|
|
|
ltrace(200) << "TrackSegment::moveUp() " << flags << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
ltracein(200);
|
|
|
|
|
* ./kite:
- Change: Propagate renaming "obstacle" -> "blockage".
- Bug/Change: In Configuration, the value of the extensionCap was too big
(1.5 lambda), reduce to 0.5 lambda. This is a problem, the extension
should be coupled to the layer as it is not the same for each METAL.
- Bug: When using TrackElement, always uses the virtual "->isFixed()" method
instead of trying to access to "->base()->isFixed()" as the base may be
NULL in case of blockage/fixed segment.
- Change: Merge PowerRails & Blockage trans-hierarchical construction (into
PowerRails). All blockages are groupeds under "blockagenet".
Allows to remove TrackBlockage & BuildBlockages.
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
ring power segments around the core must completly saturate the edges
in their segment direction. This is to prevent the global router to
use paths under the power/ground ring (may generate unsolvable configs).
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
distinguish three areas: the core (65%), the corona (90%) and the pads
(100%). Capacities on the edges are sets accordingly.
- Change: In RoutingEvent, introduce an alternative algorithm for
conflictSolve1, FindPath which try to deduce the breakpoints from a
truly explorated path. Unfortunatly this gives worst results than the
Cs1Candidates method. The why should be investigated as it's a critical
point in the algorithm.
- Change: In Manipulator::ripupPerpandicular(), when a caged perpandicular
is encountered, instead of just "stopping", rip it up and change is
axis hint (actually increase) it's axis hint so it stands a chance to
go outside the track with an obstacle.
- Change: In RoutingEvent/State::slackenTopology(), allow move up of local
segments when they are tightly constrained *and* blocked (cageds).
Partial modification of functions calls from booleans to flags.
- Bug: In NegociateWindow::NegociateOverlapCost, check for fixed segments
before trying to get DataNegociate. The lack of DataNegociate cause the
TrackElement to be discarted. It's a failsafe behavior, but it leads to
overlaps.
- Bug: In ProtectRoutingPad, in Pad Cells only, *do not* protect RoutingPad
to avoid the edge capacity over the pad to decrease to zero. This is
due to unused RoutingPads being accounted as blockages.
2010-12-04 09:25:48 -06:00
|
|
|
success = base()->moveUp ( flags );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
const vector<AutoSegment*>& invalidateds = Session::getInvalidateds();
|
|
|
|
if ( not invalidateds.empty() ) {
|
|
|
|
vector<TrackElement*> segments;
|
|
|
|
for ( size_t i=0 ; i<invalidateds.size() ; i++ ) {
|
2010-12-12 15:42:57 -06:00
|
|
|
TrackElement* segment = Session::getNegociateWindow()->addTrackSegment(invalidateds[i],false);
|
* ./kite:
- New: In BuilPowerRails & BuildBlockage, specific support for chip-level
design. The Alliance "top chip" design hierarchical structure is
hard-coded. Top level POWER/GROUND/CLOCK nets must always have the
<vsse>, <vdde>, <ck>, <vssi>, <vddi>, <ckc>, <cki> names.
Specific method to get trans-hierarchical root nets, espcially in
case of global ones (POWER/GROUND). Clock is *not* global.
Some correction in the manner obscured tracks are computeds.
- New: ProtectRoutingPad module that perform a more clean work for protecting
unused RoutingPad.
- Bug: In BuildPowerRails, uses stable_sort<> instead of sort<>, which
causes unexplained core dumps (seems to try to perform a comparison
using the "end" pseudo element). Already occured in Knik, no explanation
other than a STL bug.
- Change: Slight changes in the weights to move up. Now needs a full empty
track instead of a half one.
2010-11-16 08:00:03 -06:00
|
|
|
if ( segment != NULL ) {
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
ltrace(200) << "moved up: " << invalidateds[i] << endl;
|
* ./kite:
- New: In BuilPowerRails & BuildBlockage, specific support for chip-level
design. The Alliance "top chip" design hierarchical structure is
hard-coded. Top level POWER/GROUND/CLOCK nets must always have the
<vsse>, <vdde>, <ck>, <vssi>, <vddi>, <ckc>, <cki> names.
Specific method to get trans-hierarchical root nets, espcially in
case of global ones (POWER/GROUND). Clock is *not* global.
Some correction in the manner obscured tracks are computeds.
- New: ProtectRoutingPad module that perform a more clean work for protecting
unused RoutingPad.
- Bug: In BuildPowerRails, uses stable_sort<> instead of sort<>, which
causes unexplained core dumps (seems to try to perform a comparison
using the "end" pseudo element). Already occured in Knik, no explanation
other than a STL bug.
- Change: Slight changes in the weights to move up. Now needs a full empty
track instead of a half one.
2010-11-16 08:00:03 -06:00
|
|
|
segments.push_back ( segment );
|
2010-04-23 08:14:17 -05:00
|
|
|
// if ( (segment->getTrack() == NULL)
|
|
|
|
// or (segment->getLayer() != segment->getTrack()->getLayer()) )
|
* ./kite:
- New: In BuilPowerRails & BuildBlockage, specific support for chip-level
design. The Alliance "top chip" design hierarchical structure is
hard-coded. Top level POWER/GROUND/CLOCK nets must always have the
<vsse>, <vdde>, <ck>, <vssi>, <vddi>, <ckc>, <cki> names.
Specific method to get trans-hierarchical root nets, espcially in
case of global ones (POWER/GROUND). Clock is *not* global.
Some correction in the manner obscured tracks are computeds.
- New: ProtectRoutingPad module that perform a more clean work for protecting
unused RoutingPad.
- Bug: In BuildPowerRails, uses stable_sort<> instead of sort<>, which
causes unexplained core dumps (seems to try to perform a comparison
using the "end" pseudo element). Already occured in Knik, no explanation
other than a STL bug.
- Change: Slight changes in the weights to move up. Now needs a full empty
track instead of a half one.
2010-11-16 08:00:03 -06:00
|
|
|
segment->reschedule ( 0 );
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
for ( size_t i=0 ; i<segments.size() ; i++ ) {
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
ltrace(200) << "moved up: " << segments[i] << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if ( _data and success ) {
|
|
|
|
// _data->setState ( DataNegociate::ConflictSolve1, true );
|
|
|
|
// _data->resetRipupCount ();
|
|
|
|
// }
|
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::moveDown ( unsigned int flags )
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
|
|
|
|
ltrace(200) << "TrackSegment::moveDown() " << flags << endl;
|
|
|
|
ltracein(200);
|
|
|
|
|
|
|
|
success = base()->moveDown ( flags );
|
|
|
|
|
|
|
|
const vector<AutoSegment*>& invalidateds = Session::getInvalidateds();
|
|
|
|
if ( not invalidateds.empty() ) {
|
|
|
|
vector<TrackElement*> segments;
|
|
|
|
for ( size_t i=0 ; i<invalidateds.size() ; i++ ) {
|
|
|
|
TrackElement* segment = Session::getNegociateWindow()->addTrackSegment(invalidateds[i],false);
|
|
|
|
if ( segment != NULL ) {
|
|
|
|
ltrace(200) << "moved down: " << invalidateds[i] << endl;
|
|
|
|
segments.push_back ( segment );
|
|
|
|
// if ( (segment->getTrack() == NULL)
|
|
|
|
// or (segment->getLayer() != segment->getTrack()->getLayer()) )
|
|
|
|
segment->reschedule ( 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for ( size_t i=0 ; i<segments.size() ; i++ ) {
|
|
|
|
ltrace(200) << "moved down: " << segments[i] << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
2010-04-17 05:14:46 -05:00
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
// if ( _data and success ) {
|
|
|
|
// _data->setState ( DataNegociate::ConflictSolve1, true );
|
|
|
|
// _data->resetRipupCount ();
|
|
|
|
// }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::moveAside ( bool onLeft )
|
|
|
|
{
|
|
|
|
bool success = true;
|
|
|
|
|
|
|
|
ltrace(200) << "TrackSegment::moveAside() - " << (onLeft?"left":"right") << endl;
|
|
|
|
ltracein(200);
|
|
|
|
|
|
|
|
if ( onLeft ) base()->moveULeft ();
|
|
|
|
else base()->moveURight ();
|
|
|
|
|
|
|
|
const vector<AutoSegment*>& invalidateds = Session::getInvalidateds();
|
|
|
|
if ( not invalidateds.empty() ) {
|
|
|
|
vector<TrackElement*> segments;
|
|
|
|
for ( size_t i=0 ; i<invalidateds.size() ; i++ ) {
|
|
|
|
ltrace(200) << "moved: " << invalidateds[i] << endl;
|
2010-12-12 15:42:57 -06:00
|
|
|
segments.push_back ( Session::getNegociateWindow()->addTrackSegment(invalidateds[i],false) );
|
2010-03-09 09:24:55 -06:00
|
|
|
segments.back()->reschedule ( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( size_t i=0 ; i<segments.size() ; i++ ) {
|
|
|
|
ltrace(200) << "moved: " << segments[i] << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::getSourceDogLeg ()
|
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
if ( not hasSourceDogLeg() ) return NULL;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
unsigned int direction = Constant::perpandicular ( getDirection() );
|
|
|
|
TrackElement* dogleg = NULL;
|
|
|
|
forEach ( Segment*, isegment, base()->getAutoSource()->getSlaveComponents().getSubSet<Segment*>() ) {
|
|
|
|
dogleg = Session::lookup ( *isegment );
|
|
|
|
if ( dogleg and (dogleg->getDirection() == direction) ) {
|
|
|
|
ltrace(200) << "Source dogleg: " << dogleg << endl;
|
|
|
|
return dogleg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::getTargetDogLeg ()
|
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
if ( not hasSourceDogLeg() ) return NULL;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
unsigned int direction = Constant::perpandicular ( getDirection() );
|
|
|
|
TrackElement* dogleg = NULL;
|
|
|
|
forEach ( Segment*, isegment, base()->getAutoTarget()->getSlaveComponents().getSubSet<Segment*>() ) {
|
|
|
|
dogleg = Session::lookup ( *isegment );
|
|
|
|
if ( dogleg and (dogleg->getDirection() == direction) ) {
|
|
|
|
ltrace(200) << "Target dogleg: " << dogleg << endl;
|
|
|
|
return dogleg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::canDogLeg ( Interval interval )
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::canDogLeg(Interval) " << interval << endl;
|
|
|
|
|
|
|
|
if ( isFixed() ) {
|
|
|
|
ltrace(200) << "Failed: is fixed" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( not isLocal() ) {
|
|
|
|
ltrace(200) << "Failed: is not local" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( hasSourceDogLeg() or hasTargetDogLeg() or isSlackened() ) {
|
|
|
|
ltrace(200) << "Failed: already has source and/or target dogleg or slackened." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _base->canDogLeg(interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::makeDogLeg ( Interval interval, bool& leftDogleg )
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::makeDogLeg(Interval)" << endl;
|
|
|
|
|
|
|
|
bool upLayer = (Session::getRoutingGauge()->getLayerDepth(getLayer()) < 2);
|
|
|
|
|
|
|
|
base()->makeDogLeg ( interval, upLayer, leftDogleg );
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
return _postDogLeg ();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::canDogLeg ()
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::canDogLeg()" << endl;
|
|
|
|
|
|
|
|
if ( not isLocal() ) {
|
|
|
|
ltrace(200) << "Failed: is not local." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( isFixed() ) {
|
|
|
|
ltrace(200) << "Failed: is fixed." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( isSlackened() ) {
|
|
|
|
ltrace(200) << "Failed: is local & slackened." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( hasSourceDogLeg() || hasTargetDogLeg() ) return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::makeDogLeg ()
|
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
Katabatic::AutoContact* source = _base->getAutoSource();
|
|
|
|
Katabatic::AutoContact* target = _base->getAutoTarget();
|
|
|
|
Katabatic::GCell* gcell = _base->getAutoSource()->getGCell();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
TrackElement* dogleg = makeDogLeg ( gcell );
|
|
|
|
|
|
|
|
if ( dogleg ) {
|
|
|
|
if ( source->isTerminal() xor target->isTerminal() ) {
|
|
|
|
if ( target->isTerminal() )
|
|
|
|
source = target;
|
|
|
|
|
|
|
|
DbU::Unit axis = (_base->isHorizontal()) ? source->getX() : source->getY();
|
|
|
|
|
|
|
|
ltrace(200) << "Setting dogleg axis @" << DbU::getValueString(axis) << endl;
|
|
|
|
dogleg->setAxis ( axis );
|
|
|
|
}
|
2010-12-12 15:42:57 -06:00
|
|
|
return _postDogLeg();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
bool TrackSegment::canDogLegAt ( Katabatic::GCell* dogLegGCell, unsigned int flags )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::canDogLegAt(GCell*) " << dogLegGCell << endl;
|
|
|
|
|
|
|
|
if ( isFixed() ) {
|
|
|
|
ltrace(200) << "Cannot dogleg a fixed segment." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( isLocal() ) {
|
|
|
|
if ( hasSourceDogLeg() or hasTargetDogLeg() ) {
|
|
|
|
ltrace(200) << "Cannot dogleg again a local segment." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ( isSlackened() ) {
|
|
|
|
ltrace(200) << "Cannot dogleg a local slackened segment." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
vector<Katabatic::GCell*> gcells;
|
2010-03-09 09:24:55 -06:00
|
|
|
getGCells ( gcells );
|
|
|
|
|
|
|
|
ltrace(190) << "Source: " << *gcells.begin () << endl;
|
|
|
|
ltrace(190) << "Target: " << *gcells.rbegin() << endl;
|
|
|
|
|
|
|
|
bool isGCellInside = false;
|
|
|
|
for ( size_t igcell=0 ; igcell<gcells.size() ; igcell++ ) {
|
|
|
|
if ( dogLegGCell != gcells[igcell] ) continue;
|
|
|
|
|
|
|
|
isGCellInside = true;
|
|
|
|
if ( igcell == 0 ) {
|
|
|
|
if ( hasSourceDogLeg() ) {
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
if ( flags & TrackElement::AllowDoglegReuse ) return true;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltrace(200) << "Cannot dogleg again in source GCell." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( hasTargetDogLeg() && (igcell == gcells.size()-1) ) {
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
if ( flags & TrackElement::AllowDoglegReuse ) return true;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltrace(200) << "Cannot dogleg again in target GCell." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( not isGCellInside ) {
|
|
|
|
ltrace(200) << "dogleg GCell is outside segment support (go outside GCell active)." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
TrackElement* TrackSegment::makeDogLeg ( Katabatic::GCell* dogLegGCell )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::makeDogLeg(GCell*)" << endl;
|
|
|
|
ltrace(200) << "Break in: " << dogLegGCell << endl;
|
|
|
|
|
|
|
|
bool upLayer = (Session::getRoutingGauge()->getLayerDepth(getLayer()) < 2);
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
base()->makeDogLeg ( dogLegGCell, upLayer );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
return _postDogLeg ();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
TrackElement* TrackSegment::_postDogLeg ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
|
|
|
ltracein(200);
|
|
|
|
|
|
|
|
TrackElement* perpandicular = NULL;
|
|
|
|
|
|
|
|
const vector<AutoSegment*>& dogLegs = Session::getDogLegs();
|
|
|
|
if ( not dogLegs.empty() ) {
|
|
|
|
vector<TrackElement*> segments;
|
|
|
|
for ( size_t i=0 ; i<dogLegs.size() ; i++ ) {
|
|
|
|
ltrace(200) << "Looking up: " << dogLegs[i] << endl;
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
segments.push_back ( Session::getNegociateWindow()->addTrackSegment(dogLegs[i],false) );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
switch ( i ) {
|
|
|
|
case 0:
|
|
|
|
segments[i]->setTargetDogLeg();
|
|
|
|
segments[i]->getDataNegociate()->resetRipupCount();
|
|
|
|
|
|
|
|
if ( segments[i] != this ) {
|
|
|
|
cerr << Error ( "Incoherency in TrackSegment LUT, lookup of %p gives %p instead of %p (this)"
|
|
|
|
, dogLegs[i], segments[i], this
|
|
|
|
) << endl;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
perpandicular = segments[i];
|
|
|
|
segments[i]->setSourceDogLeg ();
|
|
|
|
segments[i]->setTargetDogLeg ();
|
|
|
|
segments[i]->setDogLegLevel ( getDogLegLevel()+1 );
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
segments[i]->setSourceDogLeg ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
// TO CHECK
|
|
|
|
// If the original TrackElement was inserted in a Track, must check
|
|
|
|
// if the new bit takes it's place or not.
|
|
|
|
//if ( getGCell() != originalGCell ) swapTrack ( segments[2] );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
for ( size_t i=0 ; i<dogLegs.size() ; i++ ) {
|
|
|
|
segments[i]->reschedule ( ((i==1) ? 0 : 1) );
|
|
|
|
}
|
|
|
|
|
|
|
|
ltrace(200) << "original: " << segments[0] << endl;
|
|
|
|
ltrace(200) << "perpand: " << segments[1] << endl;
|
|
|
|
ltrace(200) << "new paral: " << segments[2] << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
|
|
|
|
return perpandicular;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::canDesalignate () const
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::canDesalignate()" << endl;
|
|
|
|
|
|
|
|
return _base->canDesalignate();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::desalignate ()
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::desalignate()" << endl;
|
|
|
|
ltracein(200);
|
|
|
|
|
|
|
|
_base->desalignate ();
|
|
|
|
_postModify ();
|
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::_postModify ()
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::_postModify()" << endl;
|
|
|
|
ltracein(200);
|
|
|
|
|
|
|
|
unsigned int doglegLevel = getDogLegLevel() + 1;
|
|
|
|
unsigned int parallelDir = getDirection ();
|
|
|
|
unsigned int perpandicularDir = Constant::perpandicular ( parallelDir );
|
|
|
|
|
|
|
|
const vector<AutoSegment*>& invalidateds = Session::getInvalidateds();
|
2010-04-12 06:24:57 -05:00
|
|
|
vector<TrackElement*> segments;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
if ( not invalidateds.empty() ) {
|
|
|
|
for ( size_t i=0 ; i<invalidateds.size() ; i++ ) {
|
|
|
|
ltrace(200) << "invalidated: " << invalidateds[i] << endl;
|
2010-12-12 15:42:57 -06:00
|
|
|
TrackElement* segment = Session::getNegociateWindow()->addTrackSegment(invalidateds[i],false);
|
* ./kite:
- New: In BuilPowerRails & BuildBlockage, specific support for chip-level
design. The Alliance "top chip" design hierarchical structure is
hard-coded. Top level POWER/GROUND/CLOCK nets must always have the
<vsse>, <vdde>, <ck>, <vssi>, <vddi>, <ckc>, <cki> names.
Specific method to get trans-hierarchical root nets, espcially in
case of global ones (POWER/GROUND). Clock is *not* global.
Some correction in the manner obscured tracks are computeds.
- New: ProtectRoutingPad module that perform a more clean work for protecting
unused RoutingPad.
- Bug: In BuildPowerRails, uses stable_sort<> instead of sort<>, which
causes unexplained core dumps (seems to try to perform a comparison
using the "end" pseudo element). Already occured in Knik, no explanation
other than a STL bug.
- Change: Slight changes in the weights to move up. Now needs a full empty
track instead of a half one.
2010-11-16 08:00:03 -06:00
|
|
|
if ( segment != NULL )
|
|
|
|
segments.push_back ( segment );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( size_t i=0 ; i<segments.size() ; ++i ) {
|
|
|
|
TrackElement* segment = segments[i];
|
|
|
|
ltrace(200) << "Post proccess: " << segment << endl;
|
|
|
|
|
|
|
|
if ( segment->isCreated() and (segment->getDirection() == perpandicularDir) ) {
|
|
|
|
ltrace(200) << "Increasing dogleg level to: " << doglegLevel << endl;
|
|
|
|
segment->setDogLegLevel ( doglegLevel );
|
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
if ( segment->getDirection() == parallelDir ) {
|
|
|
|
forEach ( TrackElement*, iperpandicular, segment->getCollapsedPerpandiculars() ) {
|
|
|
|
ltrace(200) << "| pp: " << *iperpandicular << endl;
|
|
|
|
iperpandicular->reschedule ( 0 );
|
2010-04-12 06:24:57 -05:00
|
|
|
}
|
2010-12-12 15:42:57 -06:00
|
|
|
segment->reschedule ( 0 );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::_check () const
|
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
if ( not base() ) return true;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
bool coherency = true;
|
|
|
|
|
* ./Kite:
- New: In BuildPowerRails, special processing for the power ring segments.
The "diagonal" of vias at each corner is causing a misbehavior of the
routing algorithm (due to fully saturated GCells in one direction).
As a temporary fix, extend the segments so they form a "square corner".
(problem arise on "d_in_i(22)").
- New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()"
feature. No noticeable loss of quality or speed.
- New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism.
Allows to gets the DataNegociate of either the segment or it's parent.
- New: State::solveFullBlockages(), dedicated method to solves the case when
all the allowed tracks of a segment are blocked, tries to moves up
local segments and to break-up global ones.
- New: RoutingEventLoop, a more sophisticated way to detect looping.
Maintain a dynamic histogram of the last N (default 10) segments routeds,
with the count of how many times they have occurred. If that count
exeed 40, we *may* be facing a loop.
- Change: In State::conflictSolve1, implement new policy. The global segments
no more can be broken by local ones. The idea behind is that breaking
a global on the request of a local will only produce more cluttering
in the GCell. Globals must be keep straigth pass through, especially
inside near-saturated GCells. Globals breaking however can occurs at
another global's request.
- Change: In TrackCost, implement the new policy about locals segments that
cannot break globals segments. The sorting class now accept flags to
modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth
(to uses for strap segments) and DiscardGlobals (to uses with locals).
- Change: In TrackCost, the "distance to fixed" have now an upper bound of
50 lambdas (no need to be greater because it means it's outside the
begin & en GCells). Take account not only of fixed segment, but also
of placed segments which makes bound.
- Bug: In Track::_check(), while calling each individual TrackSegment check,
uses it as the *first* argument of the "or", otherwise it may not be
called.
- Bug: In ProtectRoutingPad, loop over segment Collections while modificating
it was producing non-deterministic results. The fact that a collection
must be not modificated while beeing iterated is becoming a more and more
painful problem.
2010-12-30 12:42:17 -06:00
|
|
|
if ( not base()->isCanonical() ) {
|
2010-03-09 09:24:55 -06:00
|
|
|
cerr << "[CHECK] " << this << " supporting AutoSegment is not canonical." << endl;
|
|
|
|
coherency = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
DbU::Unit min;
|
|
|
|
DbU::Unit max;
|
|
|
|
base()->getCanonical ( min, max );
|
|
|
|
if ( getSourceU() != min ) {
|
|
|
|
cerr << "[CHECK] " << this << " has bad source position " << DbU::getValueString(min) << "." << endl;
|
|
|
|
coherency = false;
|
|
|
|
}
|
|
|
|
if ( getTargetU() != max ) {
|
|
|
|
cerr << "[CHECK] " << this << " has bad target position " << DbU::getValueString(max) << "." << endl;
|
|
|
|
coherency = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return coherency;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string TrackSegment::_getTypeName () const
|
|
|
|
{ return "TrackSegment"; }
|
|
|
|
|
|
|
|
|
|
|
|
string TrackSegment::_getString () const
|
|
|
|
{
|
|
|
|
string s1 = _base->_getString();
|
|
|
|
string s2 = " [" + DbU::getValueString(_sourceU)
|
|
|
|
+ ":" + DbU::getValueString(_targetU) + "]"
|
|
|
|
+ " " + DbU::getValueString(_targetU-_sourceU)
|
|
|
|
+ " " + getString(_dogLegLevel)
|
|
|
|
+ " [" + ((_track) ? getString(_index) : "npos") + "] "
|
2010-04-23 08:14:17 -05:00
|
|
|
+ ((isSlackened() ) ? "S" : "-")
|
|
|
|
+ ((_track ) ? "T" : "-")
|
|
|
|
+ ((_canRipple ) ? "r" : "-")
|
|
|
|
+ ((_sourceDogLeg ) ? "s" : "-")
|
|
|
|
+ ((_targetDogLeg ) ? "t" : "-");
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
s1.insert ( s1.size()-1, s2 );
|
|
|
|
|
|
|
|
return s1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Record* TrackSegment::_getRecord () const
|
|
|
|
{
|
|
|
|
Record* record = TrackElement::_getRecord ();
|
|
|
|
record->add ( getSlot ( "_base" , _base ) );
|
|
|
|
record->add ( getSlot ( "_lock" , _lock ) );
|
|
|
|
record->add ( getSlot ( "_revalidated", _revalidated ) );
|
|
|
|
|
|
|
|
return record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // End of Kite namespace.
|