262 lines
8.9 KiB
C++
262 lines
8.9 KiB
C++
// -*- C++ -*-
|
|
//
|
|
// This file is part of the Coriolis Software.
|
|
// Copyright (c) UPMC 2008-2016, All Rights Reserved
|
|
//
|
|
// +-----------------------------------------------------------------+
|
|
// | 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 : "./TrackCost.cpp" |
|
|
// +-----------------------------------------------------------------+
|
|
|
|
|
|
#include <cstdlib>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
#include "kite/Track.h"
|
|
#include "kite/TrackCost.h"
|
|
#include "kite/Session.h"
|
|
|
|
|
|
namespace Kite {
|
|
|
|
using std::cerr;
|
|
using std::endl;
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// Class : "TrackCost".
|
|
|
|
TrackCost::TrackCost ( Track* track, Net* net )
|
|
: _flags (ZeroCost)
|
|
, _track (track)
|
|
, _begin (Track::npos)
|
|
, _end (Track::npos)
|
|
, _interval ()
|
|
, _forGlobal (false)
|
|
, _blockage (false)
|
|
, _fixed (false)
|
|
, _infinite (false)
|
|
, _hardOverlap (false)
|
|
, _overlap (false)
|
|
, _leftOverlap (false)
|
|
, _rightOverlap (false)
|
|
, _overlapGlobal (false)
|
|
, _globalEnclosed (false)
|
|
, _terminals (0)
|
|
, _delta (0)
|
|
, _deltaShared (0)
|
|
, _deltaPerpand (0)
|
|
, _axisWeight (0)
|
|
, _distanceToFixed(2*Session::getSliceHeight())
|
|
, _longuestOverlap(0)
|
|
, _dataState (0)
|
|
, _ripupCount (0)
|
|
{ }
|
|
|
|
|
|
TrackCost::TrackCost ( Track* track
|
|
, const Interval& interval
|
|
, size_t begin
|
|
, size_t end
|
|
, Net* net
|
|
, unsigned int flags
|
|
)
|
|
: _flags (flags)
|
|
, _track (track)
|
|
, _begin (begin)
|
|
, _end (end)
|
|
, _interval (interval)
|
|
, _forGlobal (false)
|
|
, _blockage (false)
|
|
, _fixed (false)
|
|
, _infinite (false)
|
|
, _hardOverlap (false)
|
|
, _overlap (false)
|
|
, _leftOverlap (false)
|
|
, _rightOverlap (false)
|
|
, _overlapGlobal (false)
|
|
, _globalEnclosed (false)
|
|
, _terminals (0)
|
|
, _delta (-interval.getSize())
|
|
, _deltaShared (0)
|
|
, _deltaPerpand (0)
|
|
, _axisWeight (0)
|
|
, _distanceToFixed(2*Session::getSliceHeight())
|
|
, _longuestOverlap(0)
|
|
, _dataState (0)
|
|
, _ripupCount (0)
|
|
{
|
|
// This is the GCell side (it is *one* cell height from the gauge).
|
|
DbU::Unit cellHeight = Session::getSliceHeight();
|
|
|
|
TrackElement* neighbor;
|
|
if ( _begin != Track::npos ) {
|
|
neighbor = _track->getSegment(_begin);
|
|
if ( neighbor and (neighbor->getNet() != net) ) {
|
|
DbU::Unit distance = interval.getVMin() - neighbor->getTargetU();
|
|
if ( distance < cellHeight )
|
|
_distanceToFixed = distance;
|
|
}
|
|
// if ( neighbor and neighbor->isFixed() ) {
|
|
// if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0;
|
|
// _distanceToFixed += interval.getVMin() - neighbor->getTargetU();
|
|
// }
|
|
}
|
|
if ( _end != Track::npos ) {
|
|
neighbor = _track->getSegment(_end);
|
|
if ( neighbor and (neighbor->getNet() != net) ) {
|
|
DbU::Unit distance = neighbor->getSourceU() - interval.getVMax();
|
|
if ( _distanceToFixed == 2*cellHeight ) _distanceToFixed = 0;
|
|
if ( distance < cellHeight )
|
|
_distanceToFixed += distance;
|
|
}
|
|
// if ( neighbor and neighbor->isFixed() ) {
|
|
// if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0;
|
|
// _distanceToFixed += neighbor->getSourceU() - interval.getVMax();
|
|
// }
|
|
}
|
|
}
|
|
|
|
TrackCost::~TrackCost ()
|
|
{ }
|
|
|
|
|
|
bool TrackCost::isFree () const
|
|
{
|
|
return /*(not _terminals) and*/ (not _overlap) and (not _infinite);
|
|
}
|
|
|
|
|
|
bool TrackCost::Compare::operator() ( const TrackCost& lhs, const TrackCost& rhs )
|
|
{
|
|
if ( lhs._infinite xor rhs._infinite ) return rhs._infinite;
|
|
|
|
if ( (_flags & TrackCost::DiscardGlobals)
|
|
and (lhs._overlapGlobal xor rhs._overlapGlobal) )
|
|
return rhs._overlapGlobal;
|
|
|
|
if ( lhs._hardOverlap xor rhs._hardOverlap ) return rhs._hardOverlap;
|
|
|
|
if ( lhs._ripupCount + (int)Session::getRipupCost() < rhs._ripupCount ) return true;
|
|
if ( lhs._ripupCount > (int)Session::getRipupCost() + rhs._ripupCount ) return false;
|
|
|
|
//int lhsRipupCost = (lhs._dataState<<2) + lhs._ripupCount;
|
|
//int rhsRipupCost = (rhs._dataState<<2) + rhs._ripupCount;
|
|
//if ( lhsRipupCost + (int)Session::getRipupCost() < rhsRipupCost ) return true;
|
|
//if ( lhsRipupCost > (int)Session::getRipupCost() + rhsRipupCost ) return false;
|
|
|
|
//if ( _flags & TrackCost::DiscardGlobals ) {
|
|
// if ( lhs._longuestOverlap < rhs._longuestOverlap ) return true;
|
|
// if ( lhs._longuestOverlap > rhs._longuestOverlap ) return false;
|
|
//}
|
|
|
|
if ( lhs._overlap xor rhs._overlap ) return rhs._overlap;
|
|
|
|
if ( lhs._terminals < rhs._terminals ) return true;
|
|
if ( lhs._terminals > rhs._terminals ) return false;
|
|
|
|
if ( not (_flags & TrackCost::IgnoreSharedLength)
|
|
or (lhs._delta > 0) or (rhs._delta > 0) ) {
|
|
if ( lhs._delta < rhs._delta ) return true;
|
|
if ( lhs._delta > rhs._delta ) return false;
|
|
}
|
|
|
|
#if 0
|
|
DbU::Unit lhsMixedWeight = 0.5*lhs._deltaPerpand;
|
|
DbU::Unit rhsMixedWeight = 0.5*rhs._deltaPerpand;
|
|
|
|
if ( not (_flags & TrackCost::IgnoreAxisWeight) ) {
|
|
lhsMixedWeight += lhsMixedWeight;
|
|
rhsMixedWeight += rhsMixedWeight;
|
|
}
|
|
|
|
if (lhsMixedWeight < rhsMixedWeight) return true;
|
|
if (lhsMixedWeight > rhsMixedWeight) return false;
|
|
#endif
|
|
|
|
if ( not (_flags & TrackCost::IgnoreAxisWeight) ) {
|
|
if ( lhs._axisWeight < rhs._axisWeight ) return true;
|
|
if ( lhs._axisWeight > rhs._axisWeight ) return false;
|
|
}
|
|
|
|
if ( lhs._deltaPerpand < rhs._deltaPerpand ) return true;
|
|
if ( lhs._deltaPerpand > rhs._deltaPerpand ) return false;
|
|
|
|
if ( lhs._distanceToFixed > rhs._distanceToFixed ) return true;
|
|
if ( lhs._distanceToFixed < rhs._distanceToFixed ) return false;
|
|
|
|
return lhs.getTrack()->getAxis() < rhs.getTrack()->getAxis();
|
|
}
|
|
|
|
|
|
bool TrackCost::CompareByDelta::operator() ( const TrackCost& lhs, const TrackCost& rhs )
|
|
{
|
|
return lhs.getDelta() < rhs.getDelta();
|
|
}
|
|
|
|
|
|
void TrackCost::consolidate ()
|
|
{
|
|
if ( not _infinite and not _hardOverlap ) {
|
|
//_deltaPerpand += - (_deltaShared << 1);
|
|
_delta += - _deltaShared;
|
|
}
|
|
}
|
|
|
|
|
|
string TrackCost::_getString () const
|
|
{
|
|
string s = "<" + _getTypeName();
|
|
|
|
s += " " + getString(_track);
|
|
s += " " + getString(_dataState);
|
|
s += "+" + getString(_ripupCount);
|
|
s += ":" + getString((_dataState<<2)+_ripupCount);
|
|
s += " " + string ( (_infinite )?"I":"-" );
|
|
s += string ( (_blockage )?"b":"-" );
|
|
s += string ( (_fixed )?"f":"-" );
|
|
s += string ( (_hardOverlap )?"h":"-" );
|
|
s += string ( (_overlap )?"o":"-" );
|
|
s += string ( (_overlapGlobal )?"g":"-" );
|
|
s += string ( (_globalEnclosed)?"e":"-" );
|
|
s += " " + getString(_terminals);
|
|
s += "/" + DbU::getValueString(_delta);
|
|
s += "/" + DbU::getValueString(_axisWeight);
|
|
s += "/" + DbU::getValueString(_deltaPerpand);
|
|
s += "/" + DbU::getValueString(_distanceToFixed);
|
|
s += "/" + DbU::getValueString(_longuestOverlap);
|
|
s += " " + getString(_dataState);
|
|
s += ">";
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
Record* TrackCost::_getRecord () const
|
|
{
|
|
Record* record = new Record ( _getString() );
|
|
record->add( getSlot ( "_track" , _track ) );
|
|
record->add( getSlot ( "_begin" , &_begin ) );
|
|
record->add( getSlot ( "_end" , &_end ) );
|
|
record->add( getSlot ( "_interval" , &_interval ) );
|
|
record->add( getSlot ( "_infinite" , _infinite ) );
|
|
record->add( getSlot ( "_overlap" , _overlap ) );
|
|
record->add( getSlot ( "_terminals" , _terminals ) );
|
|
record->add( DbU::getValueSlot( "_delta" , &_delta ) );
|
|
record->add( DbU::getValueSlot( "_deltaShared" , &_deltaShared ) );
|
|
record->add( DbU::getValueSlot( "_deltaPerpand" , &_deltaPerpand ) );
|
|
record->add( DbU::getValueSlot( "_axisWeight" , &_axisWeight ) );
|
|
record->add( DbU::getValueSlot( "_distanceToFixed", &_distanceToFixed ) );
|
|
record->add( DbU::getValueSlot( "_longuestOverlap", &_longuestOverlap ) );
|
|
|
|
return record;
|
|
}
|
|
|
|
|
|
} // Kite namespace.
|