2013-12-03 18:59:29 -06:00
|
|
|
// -*- mode: C++; explicit-buffer-name: "Session.cpp<kite>" -*-
|
2010-03-09 09:24:55 -06:00
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
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
|
|
|
// Copyright (c) UPMC 2008-2014, All Rights Reserved
|
2010-03-09 09:24:55 -06:00
|
|
|
//
|
2013-12-03 18:59:29 -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 : "./Session.cpp" |
|
2013-12-03 18:59:29 -06:00
|
|
|
// +-----------------------------------------------------------------+
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
#include "hurricane/Bug.h"
|
2013-12-03 18:59:29 -06:00
|
|
|
#include "hurricane/Point.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
#include "hurricane/Error.h"
|
2010-12-12 15:42:57 -06:00
|
|
|
#include "katabatic/GCellGrid.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
#include "kite/Session.h"
|
|
|
|
#include "kite/Track.h"
|
|
|
|
#include "kite/TrackElement.h"
|
|
|
|
#include "kite/KiteEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using namespace Kite;
|
|
|
|
|
|
|
|
|
|
|
|
const char* reopenSession =
|
|
|
|
"Kite::Session::open() :\n\n"
|
|
|
|
" Session already open for %s (internal error).";
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
} // Anonymous namespace.
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
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::Bug;
|
2013-12-03 18:59:29 -06:00
|
|
|
using Hurricane::Point;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "Session".
|
|
|
|
|
|
|
|
Session::Session ( KiteEngine* kite )
|
|
|
|
: Katabatic::Session(kite)
|
|
|
|
, _insertEvents()
|
|
|
|
, _removeEvents()
|
|
|
|
, _sortEvents ()
|
2013-12-03 18:59:29 -06:00
|
|
|
{ }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
void Session::_postCreate ()
|
2013-12-03 18:59:29 -06:00
|
|
|
{ Katabatic::Session::_postCreate(); }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
Session::~Session ()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
void Session::_preDestroy ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
_isEmpty();
|
|
|
|
Katabatic::Session::_preDestroy();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Session* Session::open ( KiteEngine* kite )
|
|
|
|
{
|
|
|
|
ltrace(110) << "Kite::Session::open()" << endl;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
Session* session = Session::get();
|
|
|
|
if (session) {
|
|
|
|
if (session->_getKiteEngine() != kite)
|
|
|
|
throw Error( reopenSession, getString(session->getKiteEngine()).c_str() );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
return session;
|
|
|
|
}
|
|
|
|
|
|
|
|
session = new Session ( kite );
|
2013-12-03 18:59:29 -06:00
|
|
|
session->_postCreate();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
return session;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Session* Session::get ( const char* message )
|
|
|
|
{ return dynamic_cast<Session*>( Katabatic::Session::get(message) ); }
|
|
|
|
|
|
|
|
|
|
|
|
Configuration* Session::getConfiguration ()
|
|
|
|
{ return Session::getKiteEngine()->getConfiguration(); }
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* Session::lookup ( Segment* segment )
|
|
|
|
{ return Session::get("Session::lookup(Segment*)")->_getKiteEngine()->_lookup(segment); }
|
|
|
|
|
|
|
|
|
|
|
|
TrackElement* Session::lookup ( AutoSegment* segment )
|
|
|
|
{ return Session::get("lookup(AutoSegment*)")->_getKiteEngine()->_lookup ( segment ); }
|
|
|
|
|
|
|
|
|
|
|
|
void Session::setInterrupt ( bool state )
|
|
|
|
{ Session::get("setInterrupt()")->_getKiteEngine()->setInterrupt(state); }
|
|
|
|
|
|
|
|
|
|
|
|
KiteEngine* Session::_getKiteEngine ()
|
|
|
|
{ return static_cast<KiteEngine*>(_katabatic); }
|
|
|
|
|
|
|
|
|
|
|
|
Net* Session::_getBlockageNet ()
|
|
|
|
{ return _getKiteEngine()->getBlockageNet(); };
|
|
|
|
|
|
|
|
|
|
|
|
NegociateWindow* Session::_getNegociateWindow ()
|
|
|
|
{ return _getKiteEngine()->getNegociateWindow(); };
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int Session::_getRipupCost ()
|
|
|
|
{ return _getKiteEngine()->getRipupCost(); };
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
Katabatic::GCell* Session::_getGCellUnder ( DbU::Unit x, DbU::Unit y )
|
2010-03-09 09:24:55 -06:00
|
|
|
{ return _getKiteEngine()->getGCellGrid()->getGCell(Point(x,y)); };
|
|
|
|
|
|
|
|
|
|
|
|
size_t Session::_revalidate ()
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
ltrace(90) << "Kite::Session::_revalidate()" << endl;
|
|
|
|
ltracein(90);
|
|
|
|
|
2010-03-09 09:24:55 -06:00
|
|
|
set<Track*> packTracks;
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) {
|
|
|
|
if (not _removeEvents[i]._segment->getTrack()) continue;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
packTracks.insert( _removeEvents[i]._segment->getTrack() );
|
|
|
|
_removeEvents[i]._segment->detach();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
_removeEvents.clear();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( set<Track*>::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it )
|
|
|
|
(*it)->doRemoval();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( size_t i=0 ; i<_insertEvents.size() ; ++i ) {
|
|
|
|
if (_insertEvents[i]._segment) {
|
|
|
|
_insertEvents[i]._track->insert( _insertEvents[i]._segment );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
if (_insertEvents[i]._marker) _insertEvents[i]._track->insert( _insertEvents[i]._marker );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
_insertEvents.clear();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
// Check if to be destroyeds are not associateds with TrackSegments.
|
|
|
|
const set<AutoSegment*>& destroyeds = getDestroyeds();
|
|
|
|
set<AutoSegment*>::const_iterator idestroyed = destroyeds.begin();
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( ; idestroyed != destroyeds.end() ; ++idestroyed ) {
|
|
|
|
if (lookup(*idestroyed)) {
|
|
|
|
ltraceout(90);
|
|
|
|
throw Error( "Destroyed AutoSegment is associated with a TrackSegment\n"
|
|
|
|
" (%s)"
|
|
|
|
, getString(*idestroyed).c_str());
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
size_t count = Katabatic::Session::_revalidate();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
Interval span;
|
2013-12-03 18:59:29 -06:00
|
|
|
const vector<AutoSegment*>& revalidateds = getRevalidateds();
|
|
|
|
//const set<Net*>& netsModificateds = getNetsModificateds();
|
|
|
|
|
|
|
|
for ( size_t i=0 ; i<revalidateds.size() ; ++i ) {
|
|
|
|
if (not revalidateds[i]->isCanonical()) continue;
|
|
|
|
|
|
|
|
//Net* currentNet = NULL;
|
|
|
|
TrackElement* trackSegment = lookup( revalidateds[i] );
|
|
|
|
|
|
|
|
if (trackSegment and trackSegment->isInvalidated()) {
|
|
|
|
trackSegment->revalidate();
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
_doglegReset();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
# if defined(CHECK_DATABASE)
|
|
|
|
unsigned int overlaps = 0;
|
|
|
|
# endif
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( set<Track*>::iterator it=_sortEvents.begin() ; it!=_sortEvents.end() ; ++it ) {
|
|
|
|
(*it)->doReorder();
|
2010-03-09 09:24:55 -06:00
|
|
|
# if defined(CHECK_DATABASE)
|
2013-12-03 18:59:29 -06:00
|
|
|
(*it)->check( overlaps, "Session::_revalidate() - track sorting." );
|
2010-03-09 09:24:55 -06:00
|
|
|
# endif
|
|
|
|
}
|
|
|
|
|
|
|
|
# if defined(CHECK_DATABASE)
|
2013-12-03 18:59:29 -06:00
|
|
|
for ( set<Track*>::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it )
|
|
|
|
(*it)->check( overlaps, "Session::_revalidate() - on packed track." );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
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
|
|
|
for ( size_t i=0 ; i<revalidateds.size() ; ++i ) {
|
|
|
|
revalidateds[i]->_check();
|
|
|
|
}
|
|
|
|
|
2010-03-09 09:24:55 -06:00
|
|
|
//_getKiteEngine()->_showOverlap ();
|
|
|
|
# endif
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
_sortEvents.clear();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
#if THIS_IS_DISABLED
|
|
|
|
if (not faileds.empty()) {
|
2010-05-11 06:04:47 -05:00
|
|
|
set<TrackElement*>::iterator ifailed = faileds.begin();
|
2010-12-12 15:42:57 -06:00
|
|
|
Katabatic::GCellVector gcells;
|
2010-05-11 06:04:47 -05:00
|
|
|
for ( ; ifailed != faileds.end() ; ++ifailed ) {
|
|
|
|
(*ifailed)->getGCells ( gcells );
|
2013-12-03 18:59:29 -06:00
|
|
|
(*ifailed)->makeDogLeg( gcells[0] );
|
2010-05-11 06:04:47 -05:00
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
count += _revalidate();
|
2010-05-11 06:04:47 -05:00
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
#endif
|
2010-05-11 06:04:47 -05:00
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
ltraceout(90);
|
2010-03-09 09:24:55 -06:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Session::_isEmpty () const
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if ( not _insertEvents.empty() or not _removeEvents.empty() or not _sortEvents.empty() ) {
|
|
|
|
cerr << Bug( " Session::checkEmpty() failed :\n"
|
|
|
|
" %u inserts, %u removes and %u sort events remains."
|
2010-03-09 09:24:55 -06:00
|
|
|
, _insertEvents.size()
|
|
|
|
, _removeEvents.size()
|
|
|
|
, _sortEvents .size() ) << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Session::_addInsertEvent ( TrackMarker* marker, Track* track )
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
_insertEvents.push_back( Event(marker,track) );
|
|
|
|
_addSortEvent( track, true );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Session::_addInsertEvent ( TrackElement* segment, Track* track )
|
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
ltrace(200) << "addInsertEvent() " << segment
|
|
|
|
<< "\n @" << track << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
if ( segment->getTrack() != NULL ) {
|
|
|
|
cerr << Bug("Session::addInsertEvent(): Segment already in Track."
|
|
|
|
"\n %s."
|
|
|
|
"\n to %s."
|
|
|
|
,getString(segment).c_str()
|
|
|
|
,getString(track).c_str()
|
|
|
|
) << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
_insertEvents.push_back( Event(segment,track) );
|
|
|
|
_addSortEvent( track, true );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Session::_addRemoveEvent ( TrackElement* segment )
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not segment->getTrack()) {
|
|
|
|
cerr << Bug( " Kite::Session::addRemoveEvent() : %s is not in any Track."
|
|
|
|
, getString(segment).c_str() ) << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ltrace(200) << "Ripup: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl;
|
2013-12-03 18:59:29 -06:00
|
|
|
_removeEvents.push_back( Event(segment,segment->getTrack()) );
|
|
|
|
_addSortEvent( segment->getTrack(), true );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Session::_addMoveEvent ( TrackElement* segment, Track* track )
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not segment->getTrack()) {
|
|
|
|
cerr << Bug( " Kite::Session::addMoveEvent() : %s has no target Track."
|
|
|
|
, getString(segment).c_str() ) << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
_addRemoveEvent( segment );
|
|
|
|
_addInsertEvent( segment, track );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Session::_addSortEvent ( Track* track, bool forced )
|
|
|
|
{
|
2013-12-03 18:59:29 -06:00
|
|
|
if (not track ) {
|
|
|
|
cerr << Bug( " Kite::Session::addSortEvent() : no Track to sort." ) << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
return;
|
|
|
|
}
|
2013-12-03 18:59:29 -06:00
|
|
|
if (forced) track->invalidate();
|
|
|
|
_sortEvents.insert( track );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string Session::_getTypeName () const
|
|
|
|
{ return "Kite::Session"; }
|
|
|
|
|
|
|
|
|
|
|
|
Record* Session::_getRecord () const
|
|
|
|
{
|
|
|
|
Record* record = Session::_getRecord ();
|
2013-12-03 18:59:29 -06:00
|
|
|
record->add( getSlot( "_sortEvents" , &_sortEvents ) );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
return record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:59:29 -06:00
|
|
|
} // Kite namespace.
|