2010-03-09 09:24:55 -06:00
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
Corrections in how to access pads terminals in Katabatic/Kite.
* Change: In Katabatic, in GCellTopology::doRp_AccessPad(), if the supporting
RoutingPad is big (more than two pitch), do not put the access
contact in the center but on the edge. This is to avoid cut violations
between the VIAs and the matrix of VIAs that may be generated under the
RoutingPad itself.
* Change: In Kite, in TrackSegment destructor, if the legnth of the wire,
without extensions is less than one picth, enlarge it so it encompass
it's source & target VIAs (to avoid notches).
* Bug: In Kite, in Track destructor, the TrackElements where detacheds,
but not deleted, causing a memory link.
2016-03-02 10:15:58 -06:00
|
|
|
// Copyright (c) UPMC 2008-2016, All Rights Reserved
|
2010-03-09 09:24:55 -06:00
|
|
|
//
|
2012-12-03 02:29:28 -06:00
|
|
|
// +-----------------------------------------------------------------+
|
2010-03-09 09:24:55 -06:00
|
|
|
// | 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" |
|
2012-12-03 02:29:28 -06:00
|
|
|
// +-----------------------------------------------------------------+
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
#include <sstream>
|
|
|
|
#include <limits>
|
|
|
|
#include "hurricane/Bug.h"
|
|
|
|
#include "hurricane/Warning.h"
|
Corrections in how to access pads terminals in Katabatic/Kite.
* Change: In Katabatic, in GCellTopology::doRp_AccessPad(), if the supporting
RoutingPad is big (more than two pitch), do not put the access
contact in the center but on the edge. This is to avoid cut violations
between the VIAs and the matrix of VIAs that may be generated under the
RoutingPad itself.
* Change: In Kite, in TrackSegment destructor, if the legnth of the wire,
without extensions is less than one picth, enlarge it so it encompass
it's source & target VIAs (to avoid notches).
* Bug: In Kite, in Track destructor, the TrackElements where detacheds,
but not deleted, causing a memory link.
2016-03-02 10:15:58 -06:00
|
|
|
#include "hurricane/BasicLayer.h"
|
2013-12-03 18:59:29 -06:00
|
|
|
#include "hurricane/Net.h"
|
|
|
|
#include "hurricane/Name.h"
|
|
|
|
#include "hurricane/RoutingPad.h"
|
|
|
|
#include "katabatic/AutoContact.h"
|
|
|
|
#include "katabatic/GCell.h"
|
|
|
|
#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"
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
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;
|
Corrections in how to access pads terminals in Katabatic/Kite.
* Change: In Katabatic, in GCellTopology::doRp_AccessPad(), if the supporting
RoutingPad is big (more than two pitch), do not put the access
contact in the center but on the edge. This is to avoid cut violations
between the VIAs and the matrix of VIAs that may be generated under the
RoutingPad itself.
* Change: In Kite, in TrackSegment destructor, if the legnth of the wire,
without extensions is less than one picth, enlarge it so it encompass
it's source & target VIAs (to avoid notches).
* Bug: In Kite, in Track destructor, the TrackElements where detacheds,
but not deleted, causing a memory link.
2016-03-02 10:15:58 -06:00
|
|
|
using Hurricane::BasicLayer;
|
2010-03-09 09:24:55 -06:00
|
|
|
using Hurricane::Net;
|
|
|
|
using Hurricane::Name;
|
2010-04-12 06:24:57 -05:00
|
|
|
using Hurricane::RoutingPad;
|
2013-12-03 18:59:29 -06:00
|
|
|
using Katabatic::SegSlackened;
|
|
|
|
using Katabatic::KbPropagate;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "TrackSegment".
|
|
|
|
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
size_t TrackSegment::_allocateds = 0;
|
|
|
|
|
|
|
|
|
|
|
|
size_t TrackSegment::getAllocateds ()
|
|
|
|
{ return _allocateds; }
|
|
|
|
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
TrackSegment::TrackSegment ( AutoSegment* segment, Track* track )
|
|
|
|
: TrackElement (track)
|
|
|
|
, _base (segment)
|
2013-12-03 18:59:29 -06:00
|
|
|
, _freedomDegree(0)
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
, _ppitch (0)
|
2010-03-09 09:24:55 -06:00
|
|
|
, _data (NULL)
|
|
|
|
, _dogLegLevel (0)
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(99) << "CTOR TrackSegment " << (void*)this << ":" << this << endl;
|
|
|
|
ltrace(99) << " over " << (void*)segment << ":" << segment << endl;
|
|
|
|
|
|
|
|
setFlags( TElemCreated|TElemLocked );
|
2010-03-09 09:24:55 -06:00
|
|
|
if (segment) {
|
2013-12-03 18:59:29 -06:00
|
|
|
_data = new DataNegociate( this );
|
|
|
|
_base->getCanonical( _sourceU, _targetU );
|
|
|
|
updateFreedomDegree();
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
updatePPitch();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
|
|
|
|
++_allocateds;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::_postCreate ()
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement::_postCreate();
|
|
|
|
base()->addObserver( getObserver() );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackSegment::~TrackSegment ()
|
2013-12-03 18:59:29 -06:00
|
|
|
{
|
|
|
|
if (_data) delete _data;
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
--_allocateds;
|
2013-12-03 18:59:29 -06:00
|
|
|
}
|
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;
|
|
|
|
|
Corrections in how to access pads terminals in Katabatic/Kite.
* Change: In Katabatic, in GCellTopology::doRp_AccessPad(), if the supporting
RoutingPad is big (more than two pitch), do not put the access
contact in the center but on the edge. This is to avoid cut violations
between the VIAs and the matrix of VIAs that may be generated under the
RoutingPad itself.
* Change: In Kite, in TrackSegment destructor, if the legnth of the wire,
without extensions is less than one picth, enlarge it so it encompass
it's source & target VIAs (to avoid notches).
* Bug: In Kite, in Track destructor, the TrackElements where detacheds,
but not deleted, causing a memory link.
2016-03-02 10:15:58 -06:00
|
|
|
DbU::Unit length = base()->getLength();
|
|
|
|
if ( (length > 0) and (length < getPPitch()) ) {
|
|
|
|
BasicLayer* layer = getLayer()->getBasicLayers().getFirst();
|
|
|
|
DbU::Unit width = base()->getWidth();
|
|
|
|
Contact* source = base()->getAutoSource()->base();
|
|
|
|
Contact* target = base()->getAutoTarget()->base();
|
|
|
|
if (isHorizontal()) {
|
|
|
|
width = std::max( width, source->getBoundingBox(layer).getHeight() );
|
|
|
|
width = std::max( width, target->getBoundingBox(layer).getHeight() );
|
|
|
|
} else {
|
|
|
|
width = std::max( width, source->getBoundingBox(layer).getWidth() );
|
|
|
|
width = std::max( width, target->getBoundingBox(layer).getWidth() );
|
|
|
|
}
|
|
|
|
base()->base()->setWidth( width );
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
base()->removeObserver( getObserver() );
|
|
|
|
TrackElement::_preDestroy();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::create ( AutoSegment* segment, Track* track, bool& created )
|
|
|
|
{
|
|
|
|
created = false;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* trackElement = Session::lookup( segment->base() );
|
|
|
|
if (not trackElement) {
|
|
|
|
TrackSegment* trackSegment = new TrackSegment( segment, track );
|
|
|
|
trackSegment->_postCreate();
|
2010-03-09 09:24:55 -06:00
|
|
|
created = true;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
trackSegment->invalidate();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltrace(200) << "TrackSegment::create(): " << trackSegment << endl;
|
|
|
|
trackElement = trackSegment;
|
|
|
|
}
|
|
|
|
|
|
|
|
return trackElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Formerly Inline Functions.
|
2013-12-03 18:59:29 -06:00
|
|
|
// Wrappeds.
|
|
|
|
AutoSegment* TrackSegment::base () const { return _base; }
|
|
|
|
bool TrackSegment::isFixed () const { return _base->isFixed(); }
|
|
|
|
bool TrackSegment::isHorizontal () const { return _base->isHorizontal(); }
|
|
|
|
bool TrackSegment::isVertical () const { return _base->isVertical(); }
|
|
|
|
bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); }
|
|
|
|
bool TrackSegment::isGlobal () const { return _base->isWeakGlobal() or _base->isGlobal(); }
|
|
|
|
bool TrackSegment::isBipoint () const { return _base->isBipoint(); }
|
|
|
|
bool TrackSegment::isTerminal () const { return _base->isTerminal(); }
|
|
|
|
bool TrackSegment::isStrongTerminal ( unsigned int flags ) const { return _base->isStrongTerminal(flags); }
|
|
|
|
bool TrackSegment::isStrap () const { return _base->isStrap(); }
|
|
|
|
bool TrackSegment::isSlackened () const { return _base->isSlackened(); }
|
|
|
|
bool TrackSegment::isDogleg () const { return _base->isDogleg(); }
|
Added support for "same layer" dogleg. Big fix for pad routing.
* Change: In Knik, in Vertex, add a "blocked" flag to signal disabled
vertexes in the grid (must not be used by the global router).
Modificate the Graph::getVertex() method so that when a vertex
is geometrically queried, if is a blocked one, return a non-blocked
neighbor. This mechanism is introduced to, at last, prevent the
global router to go *under* the pad in case of a commplete chip.
* New: In Katabatic, in AutoSegment, a new state has been added: "reduced".
A reduced segment is in the same layer as it's perpandiculars.
To be reduced, a segments has to be connected on source & target to
AutoContactTurn, both of the perpandiculars must be of the same layer
(below or above) and it's length must not exceed one pitch in the
perpandicular direction.
To reduce an AutoSegment, call ::reduce() and to revert the state,
call ::raise(). Two associated predicates are associated:
::canReduce() and ::mustRaise().
Note: No two adjacent segments can be reduced at the same time.
* Bug: In Katabatic, in GCellTopology, add a new method ::doRp_AccessPad()
to connect to the pads. Create wiring, fixed and non managed by
Katabatic, to connect the pad connector layer to the lowest routing
layers (depth 1 & 2). The former implementation was sometimes leading
to gaps (sheared contact) that *must not* occurs during the building
stage.
Remark: This bug did put under the light the fact that the initial
wiring must be created without gaps. Gaps are closed by making doglegs
on contacts. But this mechanism could only work when the database if
fully initialised (the cache is up to date). Otherwise various problems
arise, in the canonization process for example.
* New: In Katabatic, in AutoContactTerminal::getNativeConstraintBox(),
when anchored on a RoutingPad, now take account the potential rotation
of the Path's transformation. Here again, for the chip's pads.
* New: In Kite, support for reduced AutoSegment. TrackSegment associateds
to reduced AutoSegment are *not* inserted into track to become
effectively invisibles. When a segment becomes reduced, a TrackEvent
is generated to remove it. Conversely when it is raised a RoutingEvent
is created/rescheduled to insert it. All this is mostly managed inside
the Session::revalidate() method.
* New: In Kite, in KiteEngine::createGlobalGraph(), in case of a chip,
mark all global routing vertexes (Knik) that are under a pad, as blockeds.
* Bug: In Cumulus, in PadsCorona.Side.getAxis(), inversion between X and
Y coordinate of the chip size. Did not show until a non-square chip
was routed (i.e. our MIPS R3000).
* Change: In Stratus1, in st_placement.py add the ClockBuffer class for
backward compatibility with the MIPS32 bench. Have to review this
functionnality coming from the deprecated placeAndroute.py.
In st_instance.py, no longer creates the Plug ring of a Net.
In my opinion it just clutter the display until the P&R is called.
Can re-enable later as an option (in Unicorn).
* Change: In Unicorn, in cgt.py, more reliable way of loading then running
user supplied scripts. Borrowed from alliance-checker-toolkit doChip.py .
2015-08-16 16:29:28 -05:00
|
|
|
bool TrackSegment::isReduced () const { return _base->isReduced(); }
|
Implementation of pre-routing support (for clock-tree compliance).
* New: In Katabatic, in <AutoContact>, this class is no longer derived
from ExtentionGo. With the simplificated AutoContacts, there is no
reason to do so, and it will save some QuadTree insertions/deletions.
New factory function AutoContact::createFrom(Contact*) which try to
build an AutoContact on top of a Hurricane::Contact. Of course that
base contact *must fit* into one of the predefined Contact
configurations (Terminal, Turn, HTee or VTee).
NOTE: This implies that the pre-routed segments & contacts *are*
correctly articulated, which is not the case when a Cell is read
from disk in "ap" format. The pre-routing feature must be used for
now without any re-read from disk. We will implement a re-articulating
pre-process in the future.
* Change: In Katabatic, in <AutoContact> derived classes, the ::updateCache()
method now display an accurate error message if a segment is connected
but has no AutoSegment conterpart (i.e. the lookup fails).
* New: In Katabatic, in <AutoSegment>, the ::computeOptimal() method is
short-circuited for pre-routed segments, the optimal axis position is
considered to be the one it is currently on (i.e. we trust the designer).
* New: In Katabatic, in <KatabaticEngine>, the ::loadGlobalRouting()
method now accept a map of excluded nets (same as Knik). This map is
the one of pre-routed nets.
* New: In Katabatic, in layer assignment, do not try to displace fixed
segments...
* New: In Katabatic, in <AutoSegment>, new flag SegUserDefined and related
methods to know if a segment comes from the global router (Knik) or
is pre-routed (supplied by the user).
* New: In Kite, In <BuildPowerRails>, support (exclusion) for pre-routed
nets.
* New: In Kite, In <GraphicKiteEngine> new menu entry for running the
router on pre-routed nets ("Detailed Pre-Route"), also integrated
in the all-on-one route command.
* New: In Kite, In KiteEngine, new method ::_initDataBase() that group
all the initialisation steps. It is a mix of calls between Knik and
Kite initializations which are intertwinneds (may have to devellop
a shared common base at a later point). It creates the Knik grid,
then the Katabatic grid, then load pre-routed wires and power rails
and protect isolated RoutingPads.
Add support for a map of pre-routed nets (to be excluded for
Knik calls).
The method "::run()" now uses function flags, firstly to know if
it is managing pre-routed wires or general purposes ones.
* New: In Kite, in <NegociateWindow>, the "::run()" methods has now two
modes. The normal one and the 'KtPreRoutedStage' that is for routing
pre-routed nets. When in pre-route stage, the wires are fixed at the
end of this step.
* New: In Kite, in <TrackElement> add decorator for AutoSegment
isUsedDefined().
* New: In Kite, in <TrackSegment>, the various ::canDogleg() methods
returns false for a pre-routed (user-defined segment).
* New: In Kite, in PyKiteEngine, added new method runNegociatePreRouted().
2014-06-21 13:16:47 -05:00
|
|
|
bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); }
|
2016-03-06 05:37:30 -06:00
|
|
|
bool TrackSegment::isUTurn () const { return _base->isUTurn(); }
|
2013-12-03 18:59:29 -06:00
|
|
|
// Predicates.
|
|
|
|
// Accessors.
|
|
|
|
unsigned long TrackSegment::getId () const { return _base->getId(); }
|
|
|
|
unsigned int TrackSegment::getDirection () const { return _base->getDirection(); }
|
|
|
|
Net* TrackSegment::getNet () const { return _base->getNet(); }
|
|
|
|
const Layer* TrackSegment::getLayer () const { return _base->getLayer(); }
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
DbU::Unit TrackSegment::getPitch () const { return _base->getPitch(); }
|
|
|
|
DbU::Unit TrackSegment::getPPitch () const { return _ppitch; }
|
2013-12-03 18:59:29 -06:00
|
|
|
DbU::Unit TrackSegment::getAxis () const { return _base->getAxis(); }
|
|
|
|
unsigned long TrackSegment::getFreedomDegree () const { return _freedomDegree; }
|
|
|
|
unsigned int TrackSegment::getDoglegLevel () const { return _dogLegLevel; }
|
|
|
|
Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); }
|
|
|
|
Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); }
|
|
|
|
TrackElement* TrackSegment::getCanonical ( Interval& i ) { return Session::lookup( _base->getCanonical(i)->base() ); }
|
|
|
|
TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); }
|
|
|
|
// Mutators.
|
|
|
|
void TrackSegment::invalidate () { setFlags( TElemInvalidated ); _base->invalidate(); }
|
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
|
|
|
DataNegociate* TrackSegment::getDataNegociate ( unsigned int flags ) const
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (flags & KtDataSelf) 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;
|
2013-12-03 18:59:29 -06:00
|
|
|
return _track->getNext( dummy, getNet() );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* TrackSegment::getPrevious () const
|
|
|
|
{
|
|
|
|
size_t dummy = _index;
|
2013-12-03 18:59:29 -06:00
|
|
|
return _track->getPrevious( dummy, getNet() );
|
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* TrackSegment::getParent () const
|
|
|
|
{
|
|
|
|
AutoSegment* baseParent = base()->getParent();
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not baseParent) 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
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* element = Session::lookup( baseParent );
|
* ./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
|
|
|
return element;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
Interval TrackSegment::getFreeInterval () const
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not _track) return Interval(false);
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
size_t begin = _index;
|
|
|
|
size_t end = _index;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
size_t TrackSegment::getGCells ( Katabatic::GCellVector& gcells ) const
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
Katabatic::GCellVector().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;
|
|
|
|
|
2015-05-26 07:31:38 -05:00
|
|
|
for( AutoSegment* segment : base()->getAligneds() ) {
|
|
|
|
ltrace(148) << "| " << segment << endl;
|
2013-12-03 18:59:29 -06:00
|
|
|
|
2015-05-26 07:31:38 -05:00
|
|
|
Katabatic::GCell* gcell = segment->getAutoSource()->getGCell();
|
2013-12-03 18:59:29 -06:00
|
|
|
if (gcell->getIndex() < sourceGCell->getIndex()) {
|
2010-03-09 09:24:55 -06:00
|
|
|
sourceGCell = gcell;
|
|
|
|
ltrace(148) << "getGCells(): new sourceGCell: " << sourceGCell << endl;
|
|
|
|
}
|
|
|
|
|
2015-05-26 07:31:38 -05:00
|
|
|
gcell = segment->getAutoTarget()->getGCell();
|
2013-12-03 18:59:29 -06:00
|
|
|
if (gcell->getIndex() > targetGCell->getIndex()) {
|
2010-03-09 09:24:55 -06:00
|
|
|
targetGCell = gcell;
|
|
|
|
ltrace(148) << "getGCells(): new targetGCell: " << targetGCell << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
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; }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (isHorizontal()) {
|
|
|
|
gcells.push_back( sourceGCell );
|
2010-03-09 09:24:55 -06:00
|
|
|
while ( sourceGCell != targetGCell ) {
|
|
|
|
sourceGCell = sourceGCell->getRight();
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not sourceGCell) break;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
gcells.push_back( sourceGCell );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
} else {
|
2013-12-03 18:59:29 -06:00
|
|
|
gcells.push_back( sourceGCell );
|
2010-03-09 09:24:55 -06:00
|
|
|
while ( sourceGCell != targetGCell ) {
|
|
|
|
sourceGCell = sourceGCell->getUp();
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not sourceGCell) break;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
gcells.push_back( sourceGCell );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return gcells.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t TrackSegment::getPerpandicularsBound ( set<TrackElement*>& bounds )
|
|
|
|
{
|
|
|
|
bounds.clear ();
|
|
|
|
|
|
|
|
set<AutoSegment*> baseBounds;
|
|
|
|
set<AutoSegment*>::iterator ibase;
|
2013-12-03 18:59:29 -06:00
|
|
|
_base->getPerpandicularsBound( baseBounds );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( ibase=baseBounds.begin() ; ibase!=baseBounds.end() ; ++ibase ) {
|
|
|
|
TrackElement* segment = Session::lookup( *ibase );
|
|
|
|
if (segment)
|
|
|
|
bounds.insert( segment );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return bounds.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
void TrackSegment::setDoglegLevel ( unsigned int level )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (level > 15) {
|
2010-03-09 09:24:55 -06:00
|
|
|
cerr << Bug("%s has reached maximum dog leg count (15)."
|
|
|
|
,_getString().c_str()) << endl;
|
|
|
|
level = 15;
|
|
|
|
}
|
|
|
|
_dogLegLevel = level;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
void TrackSegment::updateFreedomDegree ()
|
|
|
|
{ _freedomDegree = _base->getSlack(); }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
Support of RoutingGauge, part 2.
In Katabatic & Kite, remove all hard-coded values related to track pitches.
* New: In <Session>, add more convenience function to access RoutingGauge
characteristics.
* New: In <AutoSegment>, <AutoContact>, add support for the "depth spin",
that is, if the source/target contacts are going "top" or "down".
Used to compute the perpandicular pitch. Need a small modification
of the revalidation mechanism. The observers of <AutoSegment> are
notified when the spin changes.
* New: In <AutoSegment>, the getPPitch() method allow to compute the
"perpandicular pitch". For now it is simply the greatest from the
source perpandicular pitch and the target perpandicular pitch.
Make uses of the "depth spin".
* New: In <TrackElement>, <TrackSegment>, cache the perpandicular pitch.
Updated through the notification from the observable.
2014-05-19 10:58:38 -05:00
|
|
|
void TrackSegment::updatePPitch ()
|
|
|
|
{
|
|
|
|
_ppitch = _base->getPPitch();
|
|
|
|
//cerr << "Update P/Pitch (" << DbU::toLambda(getPPitch()) << ") on " << this << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-09 09:24:55 -06:00
|
|
|
void TrackSegment::setTrack ( Track* track )
|
2013-12-03 18:59:29 -06:00
|
|
|
{ TrackElement::setTrack( track ); }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::detach ()
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::detach() - <id:" << getId() << ">" << endl;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
setTrack( NULL );
|
|
|
|
setIndex( (size_t)-1 );
|
|
|
|
setFlags( TElemLocked );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
void TrackSegment::revalidate ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
unsetFlags( TElemCreated );
|
2010-03-09 09:24:55 -06:00
|
|
|
ltrace(148) << "revalidate() - " << this << endl;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
_base->getCanonical( _sourceU, _targetU );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (_track) Session::addSortEvent( _track, true );
|
|
|
|
unsetFlags( TElemInvalidated );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::setAxis ( DbU::Unit axis, unsigned int flags )
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
_base->setAxis( axis, flags );
|
|
|
|
invalidate();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TrackSegment::swapTrack ( TrackElement* other )
|
|
|
|
{
|
2013-12-03 18:59:29 -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 ();
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (_track and otherTrack and (_track != otherTrack)) {
|
|
|
|
cerr << Error("TrackSegment::swapTrack() - swapping TrackSegments from different tracks.") << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
setTrack( NULL );
|
|
|
|
other->setTrack( NULL );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
other->setTrack( thisTrack );
|
|
|
|
other->setIndex( thisIndex );
|
|
|
|
if (thisTrack) thisTrack->setSegment( other, thisIndex );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
setTrack( otherTrack );
|
|
|
|
setIndex( otherIndex );
|
|
|
|
if (_track) _track->setSegment( this, _index );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
#if defined(CHECK_DATABASE_DISABLED)
|
2013-12-03 18:59:29 -06:00
|
|
|
if (_track) _track->_check();
|
|
|
|
else if (other->getTrack()) other->getTrack()->_check();
|
2010-03-09 09:24:55 -06:00
|
|
|
#endif
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
RoutingEvent* thisEvent = getDataNegociate(KtDataSelf)->getRoutingEvent();
|
2010-03-09 09:24:55 -06:00
|
|
|
RoutingEvent* otherEvent = other->getDataNegociate()->getRoutingEvent();
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (thisEvent ) thisEvent ->setSegment( other );
|
|
|
|
if (otherEvent) otherEvent->setSegment( this );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
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
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not _data or not _data->hasRoutingEvent())
|
|
|
|
Session::getNegociateWindow()->addRoutingEvent( this, level );
|
2010-12-12 15:42:57 -06:00
|
|
|
else {
|
2013-12-03 18:59:29 -06:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* ./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
|
2013-12-03 18:59:29 -06:00
|
|
|
{ return _base->getMaxUnderDensity( flags ); }
|
* ./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
|
|
|
|
|
|
|
|
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
|
2013-12-03 18:59:29 -06:00
|
|
|
{ return _base->canPivotDown( reserve ); }
|
* ./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
|
|
|
|
|
|
|
|
* ./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
|
2013-12-03 18:59:29 -06:00
|
|
|
{ return _base->canMoveUp( reserve, flags ); }
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::canSlacken () const
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::canSlacken() doglegLevel:" << getDoglegLevel() << endl;
|
|
|
|
return (not isSlackened() and (getDoglegLevel() <= 3)) ? _base->canSlacken(KbPropagate) : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TrackSegment::slacken ( unsigned int flags )
|
|
|
|
{
|
|
|
|
ltrace(200) << "TrackSegment::slacken()" << endl;
|
|
|
|
|
|
|
|
bool success = false;
|
|
|
|
|
|
|
|
if (not isSlackened()) {
|
|
|
|
TrackElement* perpandicular = NULL;
|
|
|
|
TrackElement* parallel = NULL;
|
|
|
|
|
|
|
|
ltracein(200);
|
|
|
|
|
|
|
|
success = base()->slacken( flags|KbPropagate );
|
|
|
|
_postDoglegs( perpandicular, parallel );
|
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
return success;
|
|
|
|
} else
|
|
|
|
cerr << Bug("TrackSegment::slacken(): NULL base or already slackened.") << endl;
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
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);
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
success = base()->moveUp( flags );
|
|
|
|
if (success) {
|
|
|
|
TrackElement* perpandicular = NULL;
|
|
|
|
TrackElement* parallel = 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
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
Session::revalidateTopology();
|
|
|
|
_postDoglegs( perpandicular, parallel );
|
|
|
|
}
|
* ./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
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::moveDown ( unsigned int flags )
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
|
|
|
|
ltrace(200) << "TrackSegment::moveDown() " << flags << endl;
|
|
|
|
ltracein(200);
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
success = base()->moveDown( flags );
|
|
|
|
if (success) {
|
|
|
|
TrackElement* perpandicular = NULL;
|
|
|
|
TrackElement* parallel = NULL;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
Session::revalidateTopology();
|
|
|
|
_postDoglegs( perpandicular, parallel );
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltraceout(200);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
bool TrackSegment::moveAside ( unsigned int flags )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
|
|
|
bool success = true;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "TrackSegment::moveAside() - "
|
|
|
|
<< ((flags&KtMoveToLeft )?"left" :"")
|
|
|
|
<< ((flags&KtMoveToRight)?"rigth":"") << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
ltracein(200);
|
2013-12-03 18:59:29 -06:00
|
|
|
if (flags & KtMoveToLeft ) base()->moveULeft ();
|
|
|
|
if (flags & KtMoveToRight) base()->moveURight();
|
2010-03-09 09:24:55 -06:00
|
|
|
ltraceout(200);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* TrackSegment::getSourceDogleg ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not hasSourceDogleg()) return NULL;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
unsigned int direction = perpandicularTo( getDirection() );
|
2010-03-09 09:24:55 -06:00
|
|
|
TrackElement* dogleg = NULL;
|
2015-05-26 07:31:38 -05:00
|
|
|
for( Segment* segment : base()->getAutoSource()->getSlaveComponents().getSubSet<Segment*>() ) {
|
|
|
|
dogleg = Session::lookup( segment );
|
2013-12-03 18:59:29 -06:00
|
|
|
if (dogleg and (dogleg->getDirection() == direction)) {
|
2010-03-09 09:24:55 -06:00
|
|
|
ltrace(200) << "Source dogleg: " << dogleg << endl;
|
|
|
|
return dogleg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* TrackSegment::getTargetDogleg ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not hasSourceDogleg()) return NULL;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
unsigned int direction = perpandicularTo( getDirection() );
|
2010-03-09 09:24:55 -06:00
|
|
|
TrackElement* dogleg = NULL;
|
2015-05-26 07:31:38 -05:00
|
|
|
for( Segment* segment : base()->getAutoTarget()->getSlaveComponents().getSubSet<Segment*>() ) {
|
|
|
|
dogleg = Session::lookup( segment );
|
2013-12-03 18:59:29 -06:00
|
|
|
if (dogleg and (dogleg->getDirection() == direction)) {
|
2010-03-09 09:24:55 -06:00
|
|
|
ltrace(200) << "Target dogleg: " << dogleg << endl;
|
|
|
|
return dogleg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
bool TrackSegment::canDogleg ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "TrackSegment::canDogleg()" << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not isLocal()) {
|
|
|
|
ltrace(200) << "Failed: is not local." << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (isFixed()) {
|
|
|
|
ltrace(200) << "Failed: is fixed." << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Implementation of pre-routing support (for clock-tree compliance).
* New: In Katabatic, in <AutoContact>, this class is no longer derived
from ExtentionGo. With the simplificated AutoContacts, there is no
reason to do so, and it will save some QuadTree insertions/deletions.
New factory function AutoContact::createFrom(Contact*) which try to
build an AutoContact on top of a Hurricane::Contact. Of course that
base contact *must fit* into one of the predefined Contact
configurations (Terminal, Turn, HTee or VTee).
NOTE: This implies that the pre-routed segments & contacts *are*
correctly articulated, which is not the case when a Cell is read
from disk in "ap" format. The pre-routing feature must be used for
now without any re-read from disk. We will implement a re-articulating
pre-process in the future.
* Change: In Katabatic, in <AutoContact> derived classes, the ::updateCache()
method now display an accurate error message if a segment is connected
but has no AutoSegment conterpart (i.e. the lookup fails).
* New: In Katabatic, in <AutoSegment>, the ::computeOptimal() method is
short-circuited for pre-routed segments, the optimal axis position is
considered to be the one it is currently on (i.e. we trust the designer).
* New: In Katabatic, in <KatabaticEngine>, the ::loadGlobalRouting()
method now accept a map of excluded nets (same as Knik). This map is
the one of pre-routed nets.
* New: In Katabatic, in layer assignment, do not try to displace fixed
segments...
* New: In Katabatic, in <AutoSegment>, new flag SegUserDefined and related
methods to know if a segment comes from the global router (Knik) or
is pre-routed (supplied by the user).
* New: In Kite, In <BuildPowerRails>, support (exclusion) for pre-routed
nets.
* New: In Kite, In <GraphicKiteEngine> new menu entry for running the
router on pre-routed nets ("Detailed Pre-Route"), also integrated
in the all-on-one route command.
* New: In Kite, In KiteEngine, new method ::_initDataBase() that group
all the initialisation steps. It is a mix of calls between Knik and
Kite initializations which are intertwinneds (may have to devellop
a shared common base at a later point). It creates the Knik grid,
then the Katabatic grid, then load pre-routed wires and power rails
and protect isolated RoutingPads.
Add support for a map of pre-routed nets (to be excluded for
Knik calls).
The method "::run()" now uses function flags, firstly to know if
it is managing pre-routed wires or general purposes ones.
* New: In Kite, in <NegociateWindow>, the "::run()" methods has now two
modes. The normal one and the 'KtPreRoutedStage' that is for routing
pre-routed nets. When in pre-route stage, the wires are fixed at the
end of this step.
* New: In Kite, in <TrackElement> add decorator for AutoSegment
isUsedDefined().
* New: In Kite, in <TrackSegment>, the various ::canDogleg() methods
returns false for a pre-routed (user-defined segment).
* New: In Kite, in PyKiteEngine, added new method runNegociatePreRouted().
2014-06-21 13:16:47 -05:00
|
|
|
if (isRouted()) {
|
|
|
|
ltrace(200) << "Failed: belongs to an already routed net." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (isSlackened()) {
|
|
|
|
ltrace(200) << "Failed: is local & slackened." << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (hasSourceDogleg() or hasTargetDogleg()) {
|
|
|
|
ltrace(200) << "Failed: already has source or target dogleg." << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (getDoglegLevel() > 3) {
|
|
|
|
ltrace(200) << "Failed: maximum dogleg level reached (4)." << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
bool TrackSegment::canDogleg ( Katabatic::GCell* doglegGCell, unsigned int flags )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "TrackSegment::canDogleg(GCell*) " << doglegGCell << endl;
|
|
|
|
ltracein(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (doglegGCell->isUnderIoPad()) {
|
|
|
|
ltrace(200) << "false: Cannot dogleg in a GCell under an I/O Pad." << endl;
|
|
|
|
ltraceout(200);
|
|
|
|
return false;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (isFixed()) {
|
|
|
|
ltrace(200) << "false: Cannot dogleg a fixed segment." << endl;
|
|
|
|
ltraceout(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Implementation of pre-routing support (for clock-tree compliance).
* New: In Katabatic, in <AutoContact>, this class is no longer derived
from ExtentionGo. With the simplificated AutoContacts, there is no
reason to do so, and it will save some QuadTree insertions/deletions.
New factory function AutoContact::createFrom(Contact*) which try to
build an AutoContact on top of a Hurricane::Contact. Of course that
base contact *must fit* into one of the predefined Contact
configurations (Terminal, Turn, HTee or VTee).
NOTE: This implies that the pre-routed segments & contacts *are*
correctly articulated, which is not the case when a Cell is read
from disk in "ap" format. The pre-routing feature must be used for
now without any re-read from disk. We will implement a re-articulating
pre-process in the future.
* Change: In Katabatic, in <AutoContact> derived classes, the ::updateCache()
method now display an accurate error message if a segment is connected
but has no AutoSegment conterpart (i.e. the lookup fails).
* New: In Katabatic, in <AutoSegment>, the ::computeOptimal() method is
short-circuited for pre-routed segments, the optimal axis position is
considered to be the one it is currently on (i.e. we trust the designer).
* New: In Katabatic, in <KatabaticEngine>, the ::loadGlobalRouting()
method now accept a map of excluded nets (same as Knik). This map is
the one of pre-routed nets.
* New: In Katabatic, in layer assignment, do not try to displace fixed
segments...
* New: In Katabatic, in <AutoSegment>, new flag SegUserDefined and related
methods to know if a segment comes from the global router (Knik) or
is pre-routed (supplied by the user).
* New: In Kite, In <BuildPowerRails>, support (exclusion) for pre-routed
nets.
* New: In Kite, In <GraphicKiteEngine> new menu entry for running the
router on pre-routed nets ("Detailed Pre-Route"), also integrated
in the all-on-one route command.
* New: In Kite, In KiteEngine, new method ::_initDataBase() that group
all the initialisation steps. It is a mix of calls between Knik and
Kite initializations which are intertwinneds (may have to devellop
a shared common base at a later point). It creates the Knik grid,
then the Katabatic grid, then load pre-routed wires and power rails
and protect isolated RoutingPads.
Add support for a map of pre-routed nets (to be excluded for
Knik calls).
The method "::run()" now uses function flags, firstly to know if
it is managing pre-routed wires or general purposes ones.
* New: In Kite, in <NegociateWindow>, the "::run()" methods has now two
modes. The normal one and the 'KtPreRoutedStage' that is for routing
pre-routed nets. When in pre-route stage, the wires are fixed at the
end of this step.
* New: In Kite, in <TrackElement> add decorator for AutoSegment
isUsedDefined().
* New: In Kite, in <TrackSegment>, the various ::canDogleg() methods
returns false for a pre-routed (user-defined segment).
* New: In Kite, in PyKiteEngine, added new method runNegociatePreRouted().
2014-06-21 13:16:47 -05:00
|
|
|
if (isRouted()) {
|
|
|
|
ltrace(200) << "false: Cannot dogleg a segment belonging to an already routed net." << endl;
|
|
|
|
ltraceout(200);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (isLocal()) {
|
|
|
|
if (hasSourceDogleg() or hasTargetDogleg()) {
|
|
|
|
ltrace(200) << "false: Cannot dogleg again a local segment." << endl;
|
|
|
|
ltraceout(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
if (isSlackened()) {
|
|
|
|
ltrace(200) << "false: Cannot dogleg a local slackened segment." << endl;
|
|
|
|
ltraceout(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (getDoglegLevel() > 3) {
|
|
|
|
ltrace(200) << "Failed: maximum dogleg level reached (4)." << endl;
|
|
|
|
ltraceout(200);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
vector<Katabatic::GCell*> gcells;
|
2013-12-03 18:59:29 -06:00
|
|
|
getGCells( gcells );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltrace(190) << "Source: " << *gcells.begin () << endl;
|
|
|
|
ltrace(190) << "Target: " << *gcells.rbegin() << endl;
|
|
|
|
|
|
|
|
bool isGCellInside = false;
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( size_t igcell=0 ; igcell<gcells.size() ; ++igcell ) {
|
|
|
|
if (doglegGCell != gcells[igcell]) continue;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
isGCellInside = true;
|
2013-12-03 18:59:29 -06:00
|
|
|
if (igcell == 0) {
|
|
|
|
if (hasSourceDogleg()) {
|
|
|
|
if (flags & KtAllowDoglegReuse) return true;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "false: Cannot dogleg again in source GCell." << endl;
|
|
|
|
ltraceout(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (hasTargetDogleg() and (igcell == gcells.size()-1)) {
|
|
|
|
if (flags & KtAllowDoglegReuse) {
|
|
|
|
ltrace(200) << "true" << endl;
|
|
|
|
ltraceout(200);
|
|
|
|
return true;
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "false: Cannot dogleg again in target GCell." << endl;
|
|
|
|
ltraceout(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not isGCellInside) {
|
|
|
|
ltrace(200) << "false: dogleg GCell is outside segment support (go outside GCell active)." << endl;
|
|
|
|
ltraceout(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "true" << endl;
|
|
|
|
ltraceout(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
bool TrackSegment::canDogleg ( Interval interval )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "TrackSegment::canDogleg(Interval) " << interval << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (isFixed()) {
|
|
|
|
ltrace(200) << "Failed: is fixed" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
Implementation of pre-routing support (for clock-tree compliance).
* New: In Katabatic, in <AutoContact>, this class is no longer derived
from ExtentionGo. With the simplificated AutoContacts, there is no
reason to do so, and it will save some QuadTree insertions/deletions.
New factory function AutoContact::createFrom(Contact*) which try to
build an AutoContact on top of a Hurricane::Contact. Of course that
base contact *must fit* into one of the predefined Contact
configurations (Terminal, Turn, HTee or VTee).
NOTE: This implies that the pre-routed segments & contacts *are*
correctly articulated, which is not the case when a Cell is read
from disk in "ap" format. The pre-routing feature must be used for
now without any re-read from disk. We will implement a re-articulating
pre-process in the future.
* Change: In Katabatic, in <AutoContact> derived classes, the ::updateCache()
method now display an accurate error message if a segment is connected
but has no AutoSegment conterpart (i.e. the lookup fails).
* New: In Katabatic, in <AutoSegment>, the ::computeOptimal() method is
short-circuited for pre-routed segments, the optimal axis position is
considered to be the one it is currently on (i.e. we trust the designer).
* New: In Katabatic, in <KatabaticEngine>, the ::loadGlobalRouting()
method now accept a map of excluded nets (same as Knik). This map is
the one of pre-routed nets.
* New: In Katabatic, in layer assignment, do not try to displace fixed
segments...
* New: In Katabatic, in <AutoSegment>, new flag SegUserDefined and related
methods to know if a segment comes from the global router (Knik) or
is pre-routed (supplied by the user).
* New: In Kite, In <BuildPowerRails>, support (exclusion) for pre-routed
nets.
* New: In Kite, In <GraphicKiteEngine> new menu entry for running the
router on pre-routed nets ("Detailed Pre-Route"), also integrated
in the all-on-one route command.
* New: In Kite, In KiteEngine, new method ::_initDataBase() that group
all the initialisation steps. It is a mix of calls between Knik and
Kite initializations which are intertwinneds (may have to devellop
a shared common base at a later point). It creates the Knik grid,
then the Katabatic grid, then load pre-routed wires and power rails
and protect isolated RoutingPads.
Add support for a map of pre-routed nets (to be excluded for
Knik calls).
The method "::run()" now uses function flags, firstly to know if
it is managing pre-routed wires or general purposes ones.
* New: In Kite, in <NegociateWindow>, the "::run()" methods has now two
modes. The normal one and the 'KtPreRoutedStage' that is for routing
pre-routed nets. When in pre-route stage, the wires are fixed at the
end of this step.
* New: In Kite, in <TrackElement> add decorator for AutoSegment
isUsedDefined().
* New: In Kite, in <TrackSegment>, the various ::canDogleg() methods
returns false for a pre-routed (user-defined segment).
* New: In Kite, in PyKiteEngine, added new method runNegociatePreRouted().
2014-06-21 13:16:47 -05:00
|
|
|
if (isRouted()) {
|
|
|
|
ltrace(200) << "Failed: belongs to an already routed net" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not isLocal()) {
|
|
|
|
ltrace(200) << "Failed: is not local" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (hasSourceDogleg() or hasTargetDogleg() or isSlackened()) {
|
|
|
|
ltrace(200) << "Failed: already has source and/or target dogleg or slackened." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getDoglegLevel() > 3) {
|
|
|
|
ltrace(200) << "Failed: maximum dogleg level reached (4)." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _base->canDogleg(interval);
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* TrackSegment::makeDogleg ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -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
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* dogleg = NULL;
|
|
|
|
TrackElement* parallel = NULL;
|
|
|
|
makeDogleg( gcell, dogleg, parallel );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (dogleg) {
|
|
|
|
if (source->isTerminal() xor target->isTerminal()) {
|
|
|
|
if (target->isTerminal())
|
|
|
|
source = target;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
DbU::Unit axis = (_base->isHorizontal()) ? source->getX() : source->getY();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "Setting dogleg axis @" << DbU::getValueString(axis) << endl;
|
|
|
|
dogleg->setAxis( axis );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
}
|
|
|
|
return dogleg;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* TrackSegment::makeDogleg ( Katabatic::GCell* dogLegGCell
|
|
|
|
, TrackElement*& perpandicular
|
|
|
|
, TrackElement*& parallel
|
|
|
|
)
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "TrackSegment::makeDogleg(GCell*)" << endl;
|
|
|
|
ltrace(200) << "Break in: " << dogLegGCell << endl;
|
|
|
|
|
|
|
|
base()->makeDogleg( dogLegGCell );
|
|
|
|
_postDoglegs( perpandicular, parallel );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
return perpandicular;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* TrackSegment::makeDogleg ( Interval interval, unsigned int& flags )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
TrackElement* perpandicular = NULL;
|
|
|
|
TrackElement* parallel = NULL;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "TrackSegment::makeDogleg(Interval)" << endl;
|
|
|
|
flags = base()->makeDogleg( interval );
|
|
|
|
_postDoglegs( perpandicular, parallel );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
return perpandicular;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
void TrackSegment::_postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "TrackSegment::_postDoglegs()" << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
ltracein(200);
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
unsigned int doglegLevel = 0;
|
|
|
|
const vector<AutoSegment*>& doglegs = Session::getDoglegs();
|
2010-04-12 06:24:57 -05:00
|
|
|
vector<TrackElement*> segments;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not doglegs.empty()) {
|
|
|
|
if (doglegs.size()%3 != 0)
|
|
|
|
cerr << Error( "Session::_postDoglegs(): Number of created segments incoherent with pure doglegs (%u)."
|
|
|
|
, doglegs.size() ) << endl;
|
|
|
|
|
|
|
|
for ( size_t i=0 ; i<doglegs.size() ; i+=3 ) {
|
|
|
|
ltrace(200) << "Looking up original: " << doglegs[i] << endl;
|
|
|
|
segments.push_back( Session::getNegociateWindow()->createTrackSegment(doglegs[i],0) );
|
|
|
|
segments[i+0]->setFlags( TElemTargetDogleg );
|
|
|
|
segments[i+0]->getDataNegociate()->resetRipupCount();
|
|
|
|
//segments[i+0]->getDataNegociate()->resetStateCount();
|
|
|
|
segments[i+0]->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars );
|
2014-10-03 09:04:12 -05:00
|
|
|
doglegLevel = segments[i+0]->getDoglegLevel();
|
|
|
|
segments[i+0]->setDoglegLevel( doglegLevel + (segments[i]->isLocal()?1:0) );
|
2013-12-03 18:59:29 -06:00
|
|
|
|
|
|
|
ltrace(200) << "Looking up new perpand: " << doglegs[i+1] << endl;
|
|
|
|
segments.push_back( Session::getNegociateWindow()->createTrackSegment(doglegs[i+1],0) );
|
|
|
|
segments[i+1]->setFlags( TElemSourceDogleg|TElemTargetDogleg );
|
2014-10-03 09:04:12 -05:00
|
|
|
segments[i+1]->setDoglegLevel( doglegLevel + 1 );
|
2013-12-03 18:59:29 -06:00
|
|
|
|
|
|
|
ltrace(200) << "Looking up new parallel: " << doglegs[i+2] << endl;
|
|
|
|
segments.push_back( Session::getNegociateWindow()->createTrackSegment(doglegs[i+2],0) );
|
|
|
|
segments[i+2]->setFlags( TElemSourceDogleg );
|
|
|
|
segments[i+2]->getDataNegociate()->resetStateCount();
|
|
|
|
segments[i+2]->getDataNegociate()->setState( segments[i+0]->getDataNegociate()->getState() );
|
2014-10-03 09:04:12 -05:00
|
|
|
segments[i+2]->setDoglegLevel( doglegLevel + (segments[i]->isLocal()?1:0) );
|
2013-12-03 18:59:29 -06:00
|
|
|
|
|
|
|
segments[i+0]->getDataNegociate()->setChildSegment( segments[i+2] );
|
|
|
|
|
|
|
|
perpandicular = segments[i+1];
|
|
|
|
parallel = segments[i+2];
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -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
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( size_t i=0 ; i<doglegs.size() ; ++i ) {
|
|
|
|
segments[i]->reschedule ( ((i%3==1) ? 0 : 1) );
|
|
|
|
const char* segPart = "Unknown";
|
|
|
|
switch ( i%3 ) {
|
|
|
|
case 0: segPart = "original "; break;
|
|
|
|
case 1: segPart = "perpand "; break;
|
|
|
|
case 2: segPart = "new paral"; break;
|
2010-04-12 06:24:57 -05:00
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(200) << "[" << (i/3) << ":" << i << "] " << segPart << ": "
|
|
|
|
<< segments[i] << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
2014-10-03 09:04:12 -05:00
|
|
|
} else {
|
|
|
|
reschedule( 1 );
|
2013-12-03 18:59:29 -06:00
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
ltraceout(200);
|
2013-12-03 18:59:29 -06:00
|
|
|
|
|
|
|
Session::doglegReset();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TrackSegment::_check () const
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not base()) return true;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
bool coherency = true;
|
|
|
|
|
2013-12-03 18:59:29 -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;
|
2013-12-03 18:59:29 -06:00
|
|
|
base()->checkPositions();
|
|
|
|
base()->getCanonical( min, max );
|
|
|
|
if (getSourceU() != min) {
|
Implementation of pre-routing support (for clock-tree compliance).
* New: In Katabatic, in <AutoContact>, this class is no longer derived
from ExtentionGo. With the simplificated AutoContacts, there is no
reason to do so, and it will save some QuadTree insertions/deletions.
New factory function AutoContact::createFrom(Contact*) which try to
build an AutoContact on top of a Hurricane::Contact. Of course that
base contact *must fit* into one of the predefined Contact
configurations (Terminal, Turn, HTee or VTee).
NOTE: This implies that the pre-routed segments & contacts *are*
correctly articulated, which is not the case when a Cell is read
from disk in "ap" format. The pre-routing feature must be used for
now without any re-read from disk. We will implement a re-articulating
pre-process in the future.
* Change: In Katabatic, in <AutoContact> derived classes, the ::updateCache()
method now display an accurate error message if a segment is connected
but has no AutoSegment conterpart (i.e. the lookup fails).
* New: In Katabatic, in <AutoSegment>, the ::computeOptimal() method is
short-circuited for pre-routed segments, the optimal axis position is
considered to be the one it is currently on (i.e. we trust the designer).
* New: In Katabatic, in <KatabaticEngine>, the ::loadGlobalRouting()
method now accept a map of excluded nets (same as Knik). This map is
the one of pre-routed nets.
* New: In Katabatic, in layer assignment, do not try to displace fixed
segments...
* New: In Katabatic, in <AutoSegment>, new flag SegUserDefined and related
methods to know if a segment comes from the global router (Knik) or
is pre-routed (supplied by the user).
* New: In Kite, In <BuildPowerRails>, support (exclusion) for pre-routed
nets.
* New: In Kite, In <GraphicKiteEngine> new menu entry for running the
router on pre-routed nets ("Detailed Pre-Route"), also integrated
in the all-on-one route command.
* New: In Kite, In KiteEngine, new method ::_initDataBase() that group
all the initialisation steps. It is a mix of calls between Knik and
Kite initializations which are intertwinneds (may have to devellop
a shared common base at a later point). It creates the Knik grid,
then the Katabatic grid, then load pre-routed wires and power rails
and protect isolated RoutingPads.
Add support for a map of pre-routed nets (to be excluded for
Knik calls).
The method "::run()" now uses function flags, firstly to know if
it is managing pre-routed wires or general purposes ones.
* New: In Kite, in <NegociateWindow>, the "::run()" methods has now two
modes. The normal one and the 'KtPreRoutedStage' that is for routing
pre-routed nets. When in pre-route stage, the wires are fixed at the
end of this step.
* New: In Kite, in <TrackElement> add decorator for AutoSegment
isUsedDefined().
* New: In Kite, in <TrackSegment>, the various ::canDogleg() methods
returns false for a pre-routed (user-defined segment).
* New: In Kite, in PyKiteEngine, added new method runNegociatePreRouted().
2014-06-21 13:16:47 -05:00
|
|
|
cerr << "[CHECK] " << this << " has bad source position "
|
|
|
|
<< "cache:" << DbU::getValueString(getSourceU()) << " vs. "
|
|
|
|
<< "canon:" << DbU::getValueString(min) << "." << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
coherency = false;
|
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
if (getTargetU() != max) {
|
Implementation of pre-routing support (for clock-tree compliance).
* New: In Katabatic, in <AutoContact>, this class is no longer derived
from ExtentionGo. With the simplificated AutoContacts, there is no
reason to do so, and it will save some QuadTree insertions/deletions.
New factory function AutoContact::createFrom(Contact*) which try to
build an AutoContact on top of a Hurricane::Contact. Of course that
base contact *must fit* into one of the predefined Contact
configurations (Terminal, Turn, HTee or VTee).
NOTE: This implies that the pre-routed segments & contacts *are*
correctly articulated, which is not the case when a Cell is read
from disk in "ap" format. The pre-routing feature must be used for
now without any re-read from disk. We will implement a re-articulating
pre-process in the future.
* Change: In Katabatic, in <AutoContact> derived classes, the ::updateCache()
method now display an accurate error message if a segment is connected
but has no AutoSegment conterpart (i.e. the lookup fails).
* New: In Katabatic, in <AutoSegment>, the ::computeOptimal() method is
short-circuited for pre-routed segments, the optimal axis position is
considered to be the one it is currently on (i.e. we trust the designer).
* New: In Katabatic, in <KatabaticEngine>, the ::loadGlobalRouting()
method now accept a map of excluded nets (same as Knik). This map is
the one of pre-routed nets.
* New: In Katabatic, in layer assignment, do not try to displace fixed
segments...
* New: In Katabatic, in <AutoSegment>, new flag SegUserDefined and related
methods to know if a segment comes from the global router (Knik) or
is pre-routed (supplied by the user).
* New: In Kite, In <BuildPowerRails>, support (exclusion) for pre-routed
nets.
* New: In Kite, In <GraphicKiteEngine> new menu entry for running the
router on pre-routed nets ("Detailed Pre-Route"), also integrated
in the all-on-one route command.
* New: In Kite, In KiteEngine, new method ::_initDataBase() that group
all the initialisation steps. It is a mix of calls between Knik and
Kite initializations which are intertwinneds (may have to devellop
a shared common base at a later point). It creates the Knik grid,
then the Katabatic grid, then load pre-routed wires and power rails
and protect isolated RoutingPads.
Add support for a map of pre-routed nets (to be excluded for
Knik calls).
The method "::run()" now uses function flags, firstly to know if
it is managing pre-routed wires or general purposes ones.
* New: In Kite, in <NegociateWindow>, the "::run()" methods has now two
modes. The normal one and the 'KtPreRoutedStage' that is for routing
pre-routed nets. When in pre-route stage, the wires are fixed at the
end of this step.
* New: In Kite, in <TrackElement> add decorator for AutoSegment
isUsedDefined().
* New: In Kite, in <TrackSegment>, the various ::canDogleg() methods
returns false for a pre-routed (user-defined segment).
* New: In Kite, in PyKiteEngine, added new method runNegociatePreRouted().
2014-06-21 13:16:47 -05:00
|
|
|
cerr << "[CHECK] " << this << " has bad target position "
|
|
|
|
<< "cache:" << DbU::getValueString(getTargetU()) << " vs. "
|
|
|
|
<< "canon:" << DbU::getValueString(max) << "." << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
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") + "] "
|
Implementation of pre-routing support (for clock-tree compliance).
* New: In Katabatic, in <AutoContact>, this class is no longer derived
from ExtentionGo. With the simplificated AutoContacts, there is no
reason to do so, and it will save some QuadTree insertions/deletions.
New factory function AutoContact::createFrom(Contact*) which try to
build an AutoContact on top of a Hurricane::Contact. Of course that
base contact *must fit* into one of the predefined Contact
configurations (Terminal, Turn, HTee or VTee).
NOTE: This implies that the pre-routed segments & contacts *are*
correctly articulated, which is not the case when a Cell is read
from disk in "ap" format. The pre-routing feature must be used for
now without any re-read from disk. We will implement a re-articulating
pre-process in the future.
* Change: In Katabatic, in <AutoContact> derived classes, the ::updateCache()
method now display an accurate error message if a segment is connected
but has no AutoSegment conterpart (i.e. the lookup fails).
* New: In Katabatic, in <AutoSegment>, the ::computeOptimal() method is
short-circuited for pre-routed segments, the optimal axis position is
considered to be the one it is currently on (i.e. we trust the designer).
* New: In Katabatic, in <KatabaticEngine>, the ::loadGlobalRouting()
method now accept a map of excluded nets (same as Knik). This map is
the one of pre-routed nets.
* New: In Katabatic, in layer assignment, do not try to displace fixed
segments...
* New: In Katabatic, in <AutoSegment>, new flag SegUserDefined and related
methods to know if a segment comes from the global router (Knik) or
is pre-routed (supplied by the user).
* New: In Kite, In <BuildPowerRails>, support (exclusion) for pre-routed
nets.
* New: In Kite, In <GraphicKiteEngine> new menu entry for running the
router on pre-routed nets ("Detailed Pre-Route"), also integrated
in the all-on-one route command.
* New: In Kite, In KiteEngine, new method ::_initDataBase() that group
all the initialisation steps. It is a mix of calls between Knik and
Kite initializations which are intertwinneds (may have to devellop
a shared common base at a later point). It creates the Knik grid,
then the Katabatic grid, then load pre-routed wires and power rails
and protect isolated RoutingPads.
Add support for a map of pre-routed nets (to be excluded for
Knik calls).
The method "::run()" now uses function flags, firstly to know if
it is managing pre-routed wires or general purposes ones.
* New: In Kite, in <NegociateWindow>, the "::run()" methods has now two
modes. The normal one and the 'KtPreRoutedStage' that is for routing
pre-routed nets. When in pre-route stage, the wires are fixed at the
end of this step.
* New: In Kite, in <TrackElement> add decorator for AutoSegment
isUsedDefined().
* New: In Kite, in <TrackSegment>, the various ::canDogleg() methods
returns false for a pre-routed (user-defined segment).
* New: In Kite, in PyKiteEngine, added new method runNegociatePreRouted().
2014-06-21 13:16:47 -05:00
|
|
|
+ ((isRouted() ) ? "R" : "-")
|
2010-04-23 08:14:17 -05:00
|
|
|
+ ((isSlackened() ) ? "S" : "-")
|
|
|
|
+ ((_track ) ? "T" : "-")
|
2013-12-03 18:59:29 -06:00
|
|
|
+ ((canRipple() ) ? "r" : "-")
|
|
|
|
+ ((hasSourceDogleg()) ? "s" : "-")
|
|
|
|
+ ((hasTargetDogleg()) ? "t" : "-");
|
2010-03-09 09:24:55 -06:00
|
|
|
|
Implementation of pre-routing support (for clock-tree compliance).
* New: In Katabatic, in <AutoContact>, this class is no longer derived
from ExtentionGo. With the simplificated AutoContacts, there is no
reason to do so, and it will save some QuadTree insertions/deletions.
New factory function AutoContact::createFrom(Contact*) which try to
build an AutoContact on top of a Hurricane::Contact. Of course that
base contact *must fit* into one of the predefined Contact
configurations (Terminal, Turn, HTee or VTee).
NOTE: This implies that the pre-routed segments & contacts *are*
correctly articulated, which is not the case when a Cell is read
from disk in "ap" format. The pre-routing feature must be used for
now without any re-read from disk. We will implement a re-articulating
pre-process in the future.
* Change: In Katabatic, in <AutoContact> derived classes, the ::updateCache()
method now display an accurate error message if a segment is connected
but has no AutoSegment conterpart (i.e. the lookup fails).
* New: In Katabatic, in <AutoSegment>, the ::computeOptimal() method is
short-circuited for pre-routed segments, the optimal axis position is
considered to be the one it is currently on (i.e. we trust the designer).
* New: In Katabatic, in <KatabaticEngine>, the ::loadGlobalRouting()
method now accept a map of excluded nets (same as Knik). This map is
the one of pre-routed nets.
* New: In Katabatic, in layer assignment, do not try to displace fixed
segments...
* New: In Katabatic, in <AutoSegment>, new flag SegUserDefined and related
methods to know if a segment comes from the global router (Knik) or
is pre-routed (supplied by the user).
* New: In Kite, In <BuildPowerRails>, support (exclusion) for pre-routed
nets.
* New: In Kite, In <GraphicKiteEngine> new menu entry for running the
router on pre-routed nets ("Detailed Pre-Route"), also integrated
in the all-on-one route command.
* New: In Kite, In KiteEngine, new method ::_initDataBase() that group
all the initialisation steps. It is a mix of calls between Knik and
Kite initializations which are intertwinneds (may have to devellop
a shared common base at a later point). It creates the Knik grid,
then the Katabatic grid, then load pre-routed wires and power rails
and protect isolated RoutingPads.
Add support for a map of pre-routed nets (to be excluded for
Knik calls).
The method "::run()" now uses function flags, firstly to know if
it is managing pre-routed wires or general purposes ones.
* New: In Kite, in <NegociateWindow>, the "::run()" methods has now two
modes. The normal one and the 'KtPreRoutedStage' that is for routing
pre-routed nets. When in pre-route stage, the wires are fixed at the
end of this step.
* New: In Kite, in <TrackElement> add decorator for AutoSegment
isUsedDefined().
* New: In Kite, in <TrackSegment>, the various ::canDogleg() methods
returns false for a pre-routed (user-defined segment).
* New: In Kite, in PyKiteEngine, added new method runNegociatePreRouted().
2014-06-21 13:16:47 -05:00
|
|
|
s1.insert( s1.size()-1, s2 );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
return s1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Record* TrackSegment::_getRecord () const
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
Record* record = TrackElement::_getRecord();
|
|
|
|
record->add( getSlot( "_base", _base ) );
|
2010-03-09 09:24:55 -06:00
|
|
|
return record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
} // Kite namespace.
|