2010-03-09 09:24:55 -06:00
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
2015-03-17 10:42:12 -05:00
|
|
|
// Copyright (c) UPMC 2008-2015, All Rights Reserved
|
2010-03-09 09:24:55 -06:00
|
|
|
//
|
2012-12-22 12:22:54 -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 : "./DataNegociate.cpp" |
|
2012-12-22 12:22:54 -06:00
|
|
|
// +-----------------------------------------------------------------+
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <sstream>
|
|
|
|
#include "hurricane/Bug.h"
|
|
|
|
#include "hurricane/DebugSession.h"
|
|
|
|
#include "katabatic/AutoSegment.h"
|
|
|
|
#include "kite/DataNegociate.h"
|
|
|
|
#include "kite/RoutingEvent.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
namespace Kite {
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
using std::cerr;
|
|
|
|
using std::endl;
|
|
|
|
using std::map;
|
|
|
|
using std::multimap;
|
|
|
|
using std::make_pair;
|
2010-03-09 09:24:55 -06:00
|
|
|
using std::ostringstream;
|
2013-12-03 18:59:29 -06:00
|
|
|
using Hurricane::Bug;
|
|
|
|
using Hurricane::DebugSession;
|
|
|
|
using Hurricane::inltrace;
|
|
|
|
using Hurricane::ltracein;
|
|
|
|
using Hurricane::ltraceout;
|
|
|
|
using Hurricane::tab;
|
|
|
|
using Katabatic::KbHorizontal;
|
|
|
|
using Katabatic::KbPropagate;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "DataNegociate".
|
|
|
|
|
|
|
|
|
|
|
|
DataNegociate::DataNegociate ( TrackElement* trackSegment )
|
2013-12-03 18:59:29 -06:00
|
|
|
: _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)
|
2010-03-09 09:24:55 -06:00
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
DataNegociate::~DataNegociate ()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
return attraction;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-09 09:24:55 -06:00
|
|
|
void DataNegociate::update ()
|
2013-12-03 18:59:29 -06:00
|
|
|
{
|
|
|
|
DebugSession::open( _trackSegment->getNet(), 148 );
|
|
|
|
|
2014-07-06 17:42:38 -05:00
|
|
|
//ltrace(500) << "Deter| DataNegociate::update() - " << _trackSegment << endl;
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(148) << "DataNegociate::update() - " << _trackSegment << endl;
|
|
|
|
ltracein(148);
|
|
|
|
|
|
|
|
vector<AutoSegment*> collapseds;
|
|
|
|
vector<AutoSegment*> perpandiculars;
|
|
|
|
map<DbU::Unit,int> attractorSpins;
|
|
|
|
|
|
|
|
_perpandiculars.clear();
|
|
|
|
AutoSegment::getTopologicalInfos( _trackSegment->base()
|
|
|
|
, collapseds
|
|
|
|
, perpandiculars
|
|
|
|
, _leftMinExtend
|
|
|
|
, _rightMinExtend
|
|
|
|
);
|
|
|
|
|
|
|
|
_terminals = AutoSegment::getTerminalCount( _trackSegment->base(), collapseds );
|
2014-07-06 17:42:38 -05:00
|
|
|
//ltrace(500) << "Deter| Terminals:" << _terminals << endl;
|
2013-12-03 18:59:29 -06:00
|
|
|
_attractors.clear();
|
|
|
|
_perpandiculars.clear();
|
|
|
|
_perpandicularFree = Interval(false);
|
|
|
|
|
|
|
|
ltrace(148) << "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 );
|
|
|
|
|
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
|
|
|
interval.inflate( DbU::fromLambda(-0.5) );
|
2013-12-03 18:59:29 -06:00
|
|
|
|
|
|
|
ltrace(148) << "| perpandicular: " << perpandiculars[i] << endl;
|
|
|
|
ltrace(148) << "| canonical: " << perpandicular << endl;
|
|
|
|
ltracein(148);
|
|
|
|
ltrace(148) << "Canonical // interval: " << interval << endl;
|
|
|
|
|
|
|
|
_perpandiculars.push_back( perpandicular );
|
|
|
|
if (perpandicular->getTrack()) {
|
|
|
|
Interval trackFree = perpandicular->getFreeInterval();
|
|
|
|
ltrace(148) << "Track Perpandicular Free: " << trackFree << endl;
|
|
|
|
|
|
|
|
_perpandicularFree.intersection( trackFree );
|
|
|
|
} else {
|
|
|
|
ltrace(148) << "Not in any track " << perpandicular << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (interval.isPonctual()) {
|
|
|
|
ltrace(148) << "Punctual attractor @" << DbU::getValueString(interval.getVMin()) << endl;
|
|
|
|
_attractors.push_back( interval.getVMin() );
|
|
|
|
ltraceout(148);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
ltrace(148) << "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;
|
|
|
|
}
|
|
|
|
ltrace(148) << "Right attractor @" << DbU::getValueString(interval.getVMax()) << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
ltraceout(148);
|
|
|
|
}
|
|
|
|
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 << "]";
|
|
|
|
ltrace(148) << s.str() << endl;
|
|
|
|
ltrace(200) << "Perpandicular Free: " << _perpandicularFree << endl;
|
|
|
|
|
|
|
|
|
|
|
|
ltraceout(148);
|
|
|
|
DebugSession::close();
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
string DataNegociate::_getString () const
|
|
|
|
{
|
|
|
|
return "<" + _getTypeName() + " "
|
2013-12-03 18:59:29 -06:00
|
|
|
+ getString(_trackSegment) + " "
|
|
|
|
+ getString(_terminals)
|
|
|
|
+ " [" + DbU::getValueString(_leftMinExtend)
|
|
|
|
+ ":" + DbU::getValueString(_rightMinExtend)
|
|
|
|
+ "]>";
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Record* DataNegociate::_getRecord () const
|
|
|
|
{
|
|
|
|
Record* record = new Record ( getString(this) );
|
2013-12-03 18:59:29 -06:00
|
|
|
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 ) );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
return record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string DataNegociate::getStateString ( DataNegociate* data )
|
|
|
|
{
|
|
|
|
ostringstream s;
|
|
|
|
switch ( data->_state ) {
|
2013-12-03 18:59:29 -06:00
|
|
|
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;
|
2010-03-09 09:24:55 -06:00
|
|
|
default:
|
|
|
|
s << "Unknown(" << data->_state << ")"; break;
|
|
|
|
}
|
|
|
|
s << ":" << data->_stateCount;
|
|
|
|
return s.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
} // Kite namespace.
|