coriolis/kite/src/TrackElement.cpp

306 lines
11 KiB
C++
Raw Normal View History

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./TrackElement.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <limits>
#include <sstream>
#include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/Net.h"
#include "hurricane/Name.h"
#include "katabatic/AutoContact.h"
#include "crlcore/RoutingGauge.h"
#include "kite/GCell.h"
#include "kite/DataNegociate.h"
#include "kite/TrackElement.h"
#include "kite/TrackCost.h"
#include "kite/Track.h"
#include "kite/Session.h"
#include "kite/RoutingEvent.h"
#include "kite/NegociateWindow.h"
namespace {
using namespace std;
using namespace Hurricane;
using namespace CRL;
using namespace Kite;
// ---------------------------------------------------------------
// Function : "DummyOverlapCost ()".
void DummyOverlapCost ( const TrackElement* segment, TrackCost& cost )
{
cerr << Warning("No overlapCost callback has been set (%s)."
,getString(segment).c_str()) << endl;
}
} // End of local namespace.
namespace Kite {
using Hurricane::Bug;
using Hurricane::Net;
using Hurricane::Name;
// -------------------------------------------------------------------
// Class : "TrackElement::Compare".
bool TrackElement::Compare::operator() ( TrackElement* lhs, TrackElement* rhs )
{
return lhs->getArea() > rhs->getArea();
}
// -------------------------------------------------------------------
// Class : "TrackElement::CompareByPosition".
//
// Return: lhs < rhs.
bool TrackElement::CompareByPosition::operator() ( const TrackElement* lhs, const TrackElement* rhs ) const
{
if ( lhs == rhs ) return false;
if ( lhs->isBlockage() xor rhs->isBlockage() )
return lhs->isBlockage();
if ( lhs->getLength() < rhs->getLength() ) return true;
if ( lhs->getLength() > rhs->getLength() ) return false;
if ( lhs->isHorizontal() xor rhs->isHorizontal() )
return rhs->isHorizontal();
if ( lhs->getAxis() > rhs->getAxis() ) return true;
if ( lhs->getAxis() < rhs->getAxis() ) return false;
if ( lhs->getSourceU() > rhs->getSourceU() ) return true;
if ( lhs->getSourceU() < rhs->getSourceU() ) return false;
if ( lhs->isBlockage() and rhs->isBlockage() ) return false;
//return lhs->getNet()->getName() < rhs->getNet()->getName();
return lhs->getId() < rhs->getId();
}
// -------------------------------------------------------------------
// Class : "TrackElement".
SegmentOverlapCostCB* TrackElement::_overlapCostCallback = DummyOverlapCost;
SegmentOverlapCostCB* TrackElement::setOverlapCostCB ( SegmentOverlapCostCB* cb )
{
SegmentOverlapCostCB* oldCb = _overlapCostCallback;
_overlapCostCallback = cb;
return oldCb;
}
// Former inline functions.
AutoSegment* TrackElement::base () const { return NULL; }
bool TrackElement::isCreated () const { return false; }
bool TrackElement::isFixed () const { return false; }
bool TrackElement::isBlockage () const { return false; }
bool TrackElement::isStrap () const { return false; }
bool TrackElement::isSlackenStrap () const { return false; }
bool TrackElement::isLocal () const { return true; }
bool TrackElement::isGlobal () const { return not isLocal(); }
bool TrackElement::isLocked () const { return false; }
bool TrackElement::isTerminal () const { return false; }
bool TrackElement::isRevalidated () const { return false; }
bool TrackElement::isRouted () const { return true; }
bool TrackElement::isSlackened () const { return false; }
bool TrackElement::isSlackenDogLeg () const { return false; }
bool TrackElement::hasSourceDogLeg () const { return false; }
bool TrackElement::hasTargetDogLeg () const { return false; }
bool TrackElement::allowOutsideGCell () const { return false; }
bool TrackElement::canGoOutsideGCell () const { return false; }
bool TrackElement::canRipple () const { return false; }
unsigned long TrackElement::getId () const { return 0; }
GCell* TrackElement::getGCell () const { return NULL; }
unsigned long TrackElement::getArea () const { return 0; }
unsigned int TrackElement::getDogLegLevel () const { return 0; }
unsigned int TrackElement::getDogLegOrder () const { return 0; }
Interval TrackElement::getSourceConstraints () const { return Interval(); }
Interval TrackElement::getTargetConstraints () const { return Interval(); }
DataNegociate* TrackElement::getDataNegociate () const { return NULL; }
TrackElements TrackElement::getCollapsedPerpandiculars () { return new TrackElements_CollapsedPerpandicular(NULL); }
void TrackElement::setAllowOutsideGCell ( bool ) { }
void TrackElement::setLock ( bool ) { }
void TrackElement::setRevalidated ( bool ) { }
void TrackElement::invalidate () { }
void TrackElement::setCanRipple ( bool ) { }
void TrackElement::setSourceDogLeg ( bool ) { }
void TrackElement::setTargetDogLeg ( bool ) { }
TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; }
bool TrackElement::canSlacken () const { return false; }
bool TrackElement::canDesalignate () const { return false; }
bool TrackElement::canPivotUp ( float ) const { return 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
bool TrackElement::canMoveUp ( float, unsigned int ) const { return false; };
bool TrackElement::canDogLeg () { return false; };
bool TrackElement::canDogLeg ( Interval ) { return false; };
bool TrackElement::canDogLegAt ( GCell*, bool allowReuse ) { return false; };
TrackElement* TrackElement::getSourceDogLeg () { return NULL; }
TrackElement* TrackElement::getTargetDogLeg () { return NULL; }
void TrackElement::dataInvalidate () { }
void TrackElement::eventInvalidate () { }
void TrackElement::setGCell ( GCell* ) { }
void TrackElement::setArea () { }
void TrackElement::setRouted ( bool ) { }
void TrackElement::setTrack ( Track* track ) { _track = track; }
void TrackElement::setDogLegLevel ( unsigned int ) { }
void TrackElement::setDogLegOrder ( unsigned int ) { }
void TrackElement::updateGCellsStiffness ( unsigned int ) { }
void TrackElement::swapTrack ( TrackElement* ) { }
void TrackElement::reschedule ( unsigned int ) { }
void TrackElement::detach () { }
void TrackElement::revalidate ( bool invalidEvent ) { }
void TrackElement::setAxis ( DbU::Unit, unsigned int flags ) { }
void TrackElement::slacken () { }
* ./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 TrackElement::moveUp ( unsigned int ) { return false; }
bool TrackElement::moveAside ( bool onLeft ) { return false; }
TrackElement* TrackElement::makeDogLeg () { return NULL; }
TrackElement* TrackElement::makeDogLeg ( Interval, bool& leftDogleg ) { return NULL; }
TrackElement* TrackElement::makeDogLeg ( GCell* ) { return NULL; }
TrackElement* TrackElement::_postDogLeg ( GCell* ) { return NULL; }
void TrackElement::_postModify () { }
void TrackElement::desalignate () { }
bool TrackElement::_check () const { return true; }
TrackElement::TrackElement ( Track* track )
: _track(track)
, _index((size_t)-1)
{ }
void TrackElement::_postCreate ()
{ }
TrackElement::~TrackElement ()
{ }
void TrackElement::_preDestroy ()
{ }
void TrackElement::destroy ()
{
_preDestroy ();
delete this;
}
TrackElement* TrackElement::getNext () const
{
size_t dummy = _index;
return _track->getNext ( dummy, getNet() );
}
TrackElement* TrackElement::getPrevious () const
{
size_t dummy = _index;
return _track->getPrevious ( dummy, getNet() );
}
Interval TrackElement::getFreeInterval ( bool useOrder ) const
{
if ( !_track ) return Interval(false);
size_t begin = _index;
size_t end = _index;
return _track->expandFreeInterval ( begin, end, Track::Inside, getNet(), useOrder );
}
size_t TrackElement::getGCells ( vector<GCell*>& gcells ) const
{
vector<GCell*>().swap ( gcells );
return gcells.size();
}
size_t TrackElement::getPerpandicularsBound ( set<TrackElement*>& bounds )
{
bounds.clear ();
return 0;
}
unsigned int TrackElement::getOrder () const
{ return numeric_limits<unsigned int>::max(); }
void TrackElement::incOverlapCost ( Net* net, TrackCost& cost ) const
{
if ( not _track or (getNet() == net) ) return;
_overlapCostCallback ( this, cost );
}
string TrackElement::_getTypeName () const
{ return "TrackElement"; }
string TrackElement::_getString () const
{ return "<" + _getTypeName() + ">"; }
Record* TrackElement::_getRecord () const
{
Record* record = new Record ( _getString() );
record->add ( getSlot ( "_track", _track ) );
record->add ( getSlot ( "_index", _index ) );
return record;
}
} // End of Kite namespace.