coriolis/kite/src/DataNegociate.cpp

279 lines
10 KiB
C++

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, 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 : "./DataNegociate.cpp" |
// +-----------------------------------------------------------------+
#include <cstdlib>
#include <sstream>
#include "hurricane/Bug.h"
#include "hurricane/DebugSession.h"
#include "katabatic/AutoSegment.h"
#include "kite/DataNegociate.h"
#include "kite/RoutingEvent.h"
namespace Kite {
using std::cerr;
using std::endl;
using std::map;
using std::multimap;
using std::make_pair;
using std::ostringstream;
using Hurricane::Bug;
using Hurricane::DebugSession;
using Hurricane::tab;
using Katabatic::KbHorizontal;
using Katabatic::KbPropagate;
// -------------------------------------------------------------------
// Class : "DataNegociate".
DataNegociate::DataNegociate ( TrackElement* trackSegment )
: _trackSegment (trackSegment)
, _childSegment (NULL)
, _routingEvent (NULL)
, _net (trackSegment->getNet())
, _state (RipupPerpandiculars)
, _stateCount (1)
, _terminals (0)
, _ripupCount (0)
, _leftMinExtend (DbU::Max)
, _rightMinExtend (DbU::Min)
, _attractors ()
, _perpandiculars ()
, _perpandicularFree(false)
, _reduceRanges { Interval(), Interval() }
{ }
DataNegociate::~DataNegociate ()
{ }
DbU::Unit DataNegociate::getWiringDelta ( DbU::Unit axis ) const
{
DbU::Unit attraction = 0;
for ( size_t i=0 ; i < _attractors.size() ; i++ ) {
if ( _attractors[i] > axis ) attraction += _attractors[i] - axis;
else attraction += axis - _attractors[i];
}
for ( size_t i=0 ; i<2 ; ++i ) {
if (_reduceRanges[i].isEmpty()) continue;
if (_reduceRanges[i].contains(axis)) attraction -= 2*_trackSegment->getPitch();
}
return attraction;
}
void DataNegociate::update ()
{
DebugSession::open( _trackSegment->getNet(), 150, 160 );
//cdebug_log(9000,0) << "Deter| DataNegociate::update() - " << _trackSegment << endl;
cdebug_log(159,1) << "DataNegociate::update() - " << _trackSegment << endl;
//size_t reduceCandidates = 0;
//DbU::Unit pitch = _trackSegment->getPitch();
vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars;
map<DbU::Unit,int> attractorSpins;
_reduceRanges[0].makeEmpty();
_reduceRanges[1].makeEmpty();
_perpandiculars.clear();
AutoSegment::getTopologicalInfos( _trackSegment->base()
, collapseds
, perpandiculars
, _leftMinExtend
, _rightMinExtend
);
_terminals = AutoSegment::getTerminalCount( _trackSegment->base(), collapseds );
//cdebug_log(9000,0) << "Deter| Terminals:" << _terminals << endl;
_attractors.clear();
_perpandiculars.clear();
_perpandicularFree = Interval(false);
cdebug_log(159,0) << "Extracting attractors from perpandiculars." << endl;
for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) {
Interval interval;
TrackElement* perpandicular;
if (perpandiculars[i]->isCanonical()) {
perpandicular = Session::lookup( perpandiculars[i]->base() );
if (perpandicular) perpandicular->getCanonical( interval );
} else {
perpandicular = Session::lookup( perpandiculars[i]->getCanonical(interval)->base() );
}
if (not perpandicular) {
cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)"
//, getString((void*)perpandiculars[i]->getCanonical(interval)->base()).c_str()
, getString(perpandiculars[i]->getCanonical(interval)).c_str()
//, getString((void*)perpandiculars[i]->base()).c_str()
, getString(perpandiculars[i]).c_str()
) << endl;
continue;
}
if (RoutingEvent::getStage() == RoutingEvent::Repair)
perpandicular->base()->setFlagsOnAligneds( Katabatic::SegUnbound );
//cerr << "perpandicular:" << perpandicular << endl;
//cerr << " " << interval << endl;
//interval.inflate( DbU::fromLambda(-0.5) );
cdebug_log(159,0) << "| perpandicular: " << perpandiculars[i] << endl;
cdebug_log(159,0) << "| canonical: " << perpandicular << endl;
cdebug_log(159,1) << "Canonical // interval: " << interval << endl;
_perpandiculars.push_back( perpandicular );
if (perpandicular->getTrack()) {
Interval trackFree = perpandicular->getFreeInterval();
cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl;
_perpandicularFree.intersection( trackFree );
} else {
cdebug_log(159,0) << "Not in any track " << perpandicular << endl;
}
#if 0
if (interval.isPonctual()) {
cdebug_log(159,0) << "Punctual attractor @" << DbU::getValueString(interval.getVMin()) << endl;
_attractors.push_back( interval.getVMin() );
cdebug_tabw(159,-1);
continue;
}
if ( (interval.getVMin() != _trackSegment->getAxis())
or AutoSegment::isTopologicalBound(perpandiculars[i]
,perpandicular->isHorizontal() ? KbHorizontal : 0
) ) {
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find( interval.getVMin() );
if (iattractor == attractorSpins.end()) {
attractorSpins.insert( make_pair(interval.getVMin(),-1) );
} else {
iattractor->second -= 1;
}
cdebug_log(159,0) << "Left attractor @" << DbU::getValueString(interval.getVMin()) << endl;
}
if ( (interval.getVMax() != _trackSegment->getAxis())
or AutoSegment::isTopologicalBound(perpandiculars[i]
,KbPropagate | (perpandicular->isHorizontal() ? KbHorizontal : 0)
) ) {
map<DbU::Unit,int>::iterator iattractor = attractorSpins.find( interval.getVMax() );
if (iattractor == attractorSpins.end()) {
attractorSpins.insert( make_pair(interval.getVMax(),1) );
} else {
iattractor->second += 1;
}
cdebug_log(159,0) << "Right attractor @" << DbU::getValueString(interval.getVMax()) << endl;
}
if (perpandicular->base()->isReduceCandidate()) {
if (reduceCandidates < 2) {
if (interval.getVMin()+DbU::fromLambda(0.5) == _trackSegment->getAxis()) {
_reduceRanges[reduceCandidates] = Interval( interval.getVMax()-pitch
, interval.getVMax()+pitch );
} else if (interval.getVMax()-DbU::fromLambda(0.5) == _trackSegment->getAxis()) {
_reduceRanges[reduceCandidates] = Interval( interval.getVMin()-pitch
, interval.getVMin()+pitch );
}
++reduceCandidates;
}
}
#endif
cdebug_tabw(159,-1);
}
if ( not _trackSegment->isTerminal() and (_perpandiculars.size() < 2) )
cerr << Bug( "Less than two perpandiculars on %s.", getString(_trackSegment).c_str() ) << endl;
map<DbU::Unit,int>::iterator iattractor = attractorSpins.begin();
for ( ; iattractor != attractorSpins.end() ; iattractor++ ) {
if (iattractor->second != 0)
_attractors.push_back( iattractor->first );
}
ostringstream s;
s << "Attractors [";
for ( size_t i=0 ; i<_attractors.size() ; i++ ) {
if ( i ) s << ", ";
s << DbU::getValueString( _attractors[i] );
}
s << "]";
cdebug_log(159,0) << s.str() << endl;
cdebug_log(159,0) << "Perpandicular Free: " << _perpandicularFree << endl;
cdebug_tabw(159,-1);
DebugSession::close();
}
string DataNegociate::_getString () const
{
return "<" + _getTypeName() + " "
+ getString(_trackSegment) + " "
+ getString(_terminals)
+ " [" + DbU::getValueString(_leftMinExtend)
+ ":" + DbU::getValueString(_rightMinExtend)
+ "]>";
}
Record* DataNegociate::_getRecord () const
{
Record* record = new Record ( getString(this) );
record->add( getSlot ( "_routingEvent" , _routingEvent ) );
record->add( getSlot ( "_trackSegment" , _trackSegment ) );
record->add( getSlot ( "_childSegment" , _childSegment ) );
record->add( getSlot ( "_terminals" , _terminals ) );
record->add( getSlot ( "_ripupCount" , _ripupCount ) );
record->add( DbU::getValueSlot( "_leftMinExtend" , &_leftMinExtend ) );
record->add( DbU::getValueSlot( "_rightMinExtend", &_rightMinExtend ) );
record->add( getSlot ( "_net" , _net ) );
return record;
}
string DataNegociate::getStateString ( DataNegociate* data )
{
ostringstream s;
switch ( data->_state ) {
case RipupPerpandiculars: s << "RipupPerpandiculars"; break;
case Minimize: s << "Minimize"; break;
case Dogleg: s << "Dogleg"; break;
case Slacken: s << "Slacken"; break;
case ConflictSolveByHistory: s << "ConflictSolveByHistory1"; break;
case ConflictSolveByPlaceds: s << "ConflictSolveByPlaceds"; break;
case LocalVsGlobal: s << "LocalVsGlobal"; break;
case MoveUp: s << "MoveUp"; break;
case MaximumSlack: s << "MaximumSlack"; break;
case Unimplemented: s << "Unimplemented"; break;
case Repair: s << "REPAIR"; break;
default:
s << "Unknown(" << data->_state << ")"; break;
}
s << ":" << data->_stateCount;
return s.str();
}
} // Kite namespace.