coriolis/kite/src/RoutingPlane.cpp

197 lines
5.8 KiB
C++
Raw Normal View History

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./RoutingPlane.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include "hurricane/Error.h"
#include "hurricane/Box.h"
#include "hurricane/Cell.h"
#include "crlcore/RoutingLayerGauge.h"
#include "kite/HorizontalTrack.h"
#include "kite/VerticalTrack.h"
#include "kite/RoutingPlane.h"
#include "kite/KiteEngine.h"
namespace {
const char* badLayerGauge =
"RoutingPlane::create() :\n\n"
" No plane at depth %u in %s.";
} // End of local namespace.
namespace Kite {
using std::cerr;
using std::endl;
using Hurricane::tab;
using Hurricane::inltrace;
using Hurricane::ltracein;
using Hurricane::ltraceout;
using Hurricane::Error;
using Hurricane::Box;
using Hurricane::Cell;
// -------------------------------------------------------------------
// Class : "RoutingPlane".
RoutingPlane::RoutingPlane ( KiteEngine* kite, size_t depth )
: _kite (kite)
, _layerGauge(kite->getLayerGauge(depth))
, _depth (depth)
, _tracks ()
{ }
RoutingPlane::~RoutingPlane ()
{ }
void RoutingPlane::destroy ()
{
ltrace(90) << "RoutingPlane::destroy() - "
<< (void*)this << " " << this << endl;
ltracein(90);
for ( size_t index = 0 ; index < _tracks.size() ; index++ )
_tracks[index]->destroy ();
delete this;
ltraceout(90);
}
RoutingPlane* RoutingPlane::create ( KiteEngine* kite, size_t depth )
{
RoutingPlane* plane = new RoutingPlane ( kite, depth );
if ( !plane->_layerGauge )
throw Error ( badLayerGauge, depth, getString(kite->getRoutingGauge()).c_str() );
size_t trackNumber;
Box abutmentBox = kite->getCell()->getAbutmentBox();
if ( plane->getLayerGauge()->getDirection() & Constant::Horizontal ) {
plane->_trackMin = abutmentBox.getXMin () - DbU::lambda (2.0);
plane->_trackMax = abutmentBox.getXMax () + DbU::lambda (2.0);
plane->_axisMin = abutmentBox.getYMin ();
plane->_axisMax = abutmentBox.getYMax ();
trackNumber = plane->computeTracksSize ();
} else {
plane->_trackMin = abutmentBox.getYMin () - DbU::lambda (2.0);
plane->_trackMax = abutmentBox.getYMax () + DbU::lambda (2.0);
plane->_axisMin = abutmentBox.getXMin ();
plane->_axisMax = abutmentBox.getXMax ();
trackNumber = plane->computeTracksSize ();
}
plane->_tracks.reserve ( trackNumber );
for ( size_t index = 0 ; index < trackNumber ; index++ ) {
if ( plane->getLayerGauge()->getDirection() & Constant::Horizontal ) {
plane->_tracks.push_back ( HorizontalTrack::create ( plane, index ) );
} else {
plane->_tracks.push_back ( VerticalTrack::create ( plane, index ) );
}
}
return plane;
}
RoutingPlane* RoutingPlane::getTop () const
{ return getKiteEngine()->getRoutingPlaneByIndex ( getDepth()+1 ); }
RoutingPlane* RoutingPlane::getBottom () const
{
if ( !getDepth() ) return NULL;
return getKiteEngine()->getRoutingPlaneByIndex ( getDepth()-1 );
}
Track* RoutingPlane::getTrackByIndex ( size_t index ) const
{
if ( index >= getTracksSize() ) return NULL;
return _tracks[index];
}
Track* RoutingPlane::getTrackByPosition ( DbU::Unit axis, unsigned int mode ) const
{
return getTrackByIndex ( getLayerGauge()->getTrackIndex ( getAxisMin()
, getAxisMax()
, axis
, mode
) );
}
bool RoutingPlane::_check ( unsigned int& overlaps ) const
{
bool coherency = true;
for ( size_t i=0 ; i<_tracks.size() ; i++ ) {
* ./Kite: - New: In BuildPowerRails, special processing for the power ring segments. The "diagonal" of vias at each corner is causing a misbehavior of the routing algorithm (due to fully saturated GCells in one direction). As a temporary fix, extend the segments so they form a "square corner". (problem arise on "d_in_i(22)"). - New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()" feature. No noticeable loss of quality or speed. - New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism. Allows to gets the DataNegociate of either the segment or it's parent. - New: State::solveFullBlockages(), dedicated method to solves the case when all the allowed tracks of a segment are blocked, tries to moves up local segments and to break-up global ones. - New: RoutingEventLoop, a more sophisticated way to detect looping. Maintain a dynamic histogram of the last N (default 10) segments routeds, with the count of how many times they have occurred. If that count exeed 40, we *may* be facing a loop. - Change: In State::conflictSolve1, implement new policy. The global segments no more can be broken by local ones. The idea behind is that breaking a global on the request of a local will only produce more cluttering in the GCell. Globals must be keep straigth pass through, especially inside near-saturated GCells. Globals breaking however can occurs at another global's request. - Change: In TrackCost, implement the new policy about locals segments that cannot break globals segments. The sorting class now accept flags to modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth (to uses for strap segments) and DiscardGlobals (to uses with locals). - Change: In TrackCost, the "distance to fixed" have now an upper bound of 50 lambdas (no need to be greater because it means it's outside the begin & en GCells). Take account not only of fixed segment, but also of placed segments which makes bound. - Bug: In Track::_check(), while calling each individual TrackSegment check, uses it as the *first* argument of the "or", otherwise it may not be called. - Bug: In ProtectRoutingPad, loop over segment Collections while modificating it was producing non-deterministic results. The fact that a collection must be not modificated while beeing iterated is becoming a more and more painful problem.
2010-12-30 12:42:17 -06:00
coherency = _tracks[i]->_check(overlaps) and coherency;
}
return coherency;
}
string RoutingPlane::_getString () const
{
return "<" + _getTypeName() + " @"
+ getString(_depth) + " ["
+ getString(_tracks.size()) + "/"
+ getString(_tracks.capacity())
+ "]>";
}
Record* RoutingPlane::_getRecord () const
{
Record* record = new Record ( getString(this) );
record->add ( getSlot ( "_kite" , _kite ) );
record->add ( getSlot ( "_layerGauge" , _layerGauge ) );
record->add ( getSlot ( "_depth" , &_depth ) );
record->add ( DbU::getValueSlot ( "_axisMin" , &_axisMin ) );
record->add ( DbU::getValueSlot ( "_axisMax" , &_axisMax ) );
record->add ( DbU::getValueSlot ( "_trackMin" , &_trackMin ) );
record->add ( DbU::getValueSlot ( "_trackMax" , &_trackMax ) );
record->add ( getSlot ( "_tracks" , &_tracks ) );
return record;
}
} // End of Kite namespace.