2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
2010-04-23 08:14:17 -05:00
|
|
|
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
|
2010-03-09 09:24:55 -06:00
|
|
|
//
|
|
|
|
// ===================================================================
|
|
|
|
//
|
|
|
|
// $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 : "./NegociateWindow.cpp" |
|
|
|
|
// | *************************************************************** |
|
|
|
|
// | U p d a t e s |
|
|
|
|
// | |
|
|
|
|
// x-----------------------------------------------------------------x
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
#include <vector>
|
2010-03-09 09:24:55 -06:00
|
|
|
#include <algorithm>
|
|
|
|
#include <iomanip>
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
#include "hurricane/Warning.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
#include "hurricane/Bug.h"
|
|
|
|
#include "hurricane/RoutingPad.h"
|
|
|
|
#include "hurricane/Net.h"
|
|
|
|
#include "hurricane/Cell.h"
|
2010-04-28 10:44:07 -05:00
|
|
|
#include "crlcore/Utilities.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
#include "crlcore/AllianceFramework.h"
|
2010-08-22 07:38:27 -05:00
|
|
|
#include "crlcore/Measures.h"
|
2010-12-15 09:12:00 -06:00
|
|
|
#include "crlcore/Histogram.h"
|
2010-12-12 15:42:57 -06:00
|
|
|
#include "katabatic/AutoContact.h"
|
|
|
|
#include "katabatic/GCellGrid.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
#include "kite/DataNegociate.h"
|
|
|
|
#include "kite/TrackElement.h"
|
|
|
|
#include "kite/TrackMarker.h"
|
|
|
|
#include "kite/TrackCost.h"
|
|
|
|
#include "kite/Track.h"
|
2010-12-12 15:42:57 -06:00
|
|
|
#include "kite/TrackSegment.h"
|
2010-03-09 09:24:55 -06:00
|
|
|
#include "kite/RoutingPlane.h"
|
|
|
|
#include "kite/RoutingEventQueue.h"
|
|
|
|
#include "kite/RoutingEventHistory.h"
|
|
|
|
#include "kite/NegociateWindow.h"
|
|
|
|
#include "kite/KiteEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace Hurricane;
|
|
|
|
using namespace CRL;
|
|
|
|
using namespace Kite;
|
|
|
|
|
|
|
|
|
|
|
|
void NegociateOverlapCost ( const TrackElement* segment, TrackCost& cost )
|
|
|
|
{
|
|
|
|
Interval intersect = segment->getCanonicalInterval();
|
|
|
|
|
|
|
|
if ( not intersect.intersect ( cost.getInterval() ) ) return;
|
|
|
|
|
* ./kite:
- Change: Propagate renaming "obstacle" -> "blockage".
- Bug/Change: In Configuration, the value of the extensionCap was too big
(1.5 lambda), reduce to 0.5 lambda. This is a problem, the extension
should be coupled to the layer as it is not the same for each METAL.
- Bug: When using TrackElement, always uses the virtual "->isFixed()" method
instead of trying to access to "->base()->isFixed()" as the base may be
NULL in case of blockage/fixed segment.
- Change: Merge PowerRails & Blockage trans-hierarchical construction (into
PowerRails). All blockages are groupeds under "blockagenet".
Allows to remove TrackBlockage & BuildBlockages.
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
ring power segments around the core must completly saturate the edges
in their segment direction. This is to prevent the global router to
use paths under the power/ground ring (may generate unsolvable configs).
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
distinguish three areas: the core (65%), the corona (90%) and the pads
(100%). Capacities on the edges are sets accordingly.
- Change: In RoutingEvent, introduce an alternative algorithm for
conflictSolve1, FindPath which try to deduce the breakpoints from a
truly explorated path. Unfortunatly this gives worst results than the
Cs1Candidates method. The why should be investigated as it's a critical
point in the algorithm.
- Change: In Manipulator::ripupPerpandicular(), when a caged perpandicular
is encountered, instead of just "stopping", rip it up and change is
axis hint (actually increase) it's axis hint so it stands a chance to
go outside the track with an obstacle.
- Change: In RoutingEvent/State::slackenTopology(), allow move up of local
segments when they are tightly constrained *and* blocked (cageds).
Partial modification of functions calls from booleans to flags.
- Bug: In NegociateWindow::NegociateOverlapCost, check for fixed segments
before trying to get DataNegociate. The lack of DataNegociate cause the
TrackElement to be discarted. It's a failsafe behavior, but it leads to
overlaps.
- Bug: In ProtectRoutingPad, in Pad Cells only, *do not* protect RoutingPad
to avoid the edge capacity over the pad to decrease to zero. This is
due to unused RoutingPads being accounted as blockages.
2010-12-04 09:25:48 -06:00
|
|
|
if ( segment->isBlockage() or segment->isFixed() ) {
|
2010-12-12 15:42:57 -06:00
|
|
|
ltrace(200) << "Infinite cost from: " << segment << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
cost.setInfinite ();
|
|
|
|
cost.setOverlap ();
|
|
|
|
cost.setHardOverlap ();
|
|
|
|
cost.setBlockage ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( cost.getInterval().getVMax() > intersect.getVMax() ) cost.setLeftOverlap();
|
|
|
|
if ( cost.getInterval().getVMin() < intersect.getVMin() ) cost.setRightOverlap();
|
|
|
|
|
|
|
|
if ( not intersect.contains(cost.getInterval()) )
|
|
|
|
intersect.intersection ( cost.getInterval() );
|
|
|
|
|
|
|
|
DataNegociate* data = segment->getDataNegociate ();
|
|
|
|
if ( not data ) return;
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
cost.mergeRipupCount ( data->getRipupCount() );
|
|
|
|
if ( segment->isLocal() ) {
|
|
|
|
cost.mergeDataState ( data->getState() );
|
|
|
|
if ( data->getState() >= DataNegociate::LocalVsGlobal ) {
|
|
|
|
ltrace(200) << "MaximumSlack/LocalVsGlobal for " << segment << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
// if ( data->getRipupCount() > 3 ) {
|
|
|
|
// ltrace(200) << "Infinite cost from: " << segment << endl;
|
|
|
|
// cost.setFixed ();
|
|
|
|
// cost.setInfinite ();
|
|
|
|
// cost.setOverlap ();
|
|
|
|
// cost.setHardOverlap ();
|
|
|
|
// return;
|
|
|
|
// }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
cost.setOverlap ();
|
|
|
|
cost.incTerminals ( data->getCost().getTerminals()*100 );
|
|
|
|
cost.incDelta ( intersect.getSize() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void loadRoutingPads ( NegociateWindow* nw )
|
|
|
|
{
|
|
|
|
AllianceFramework* af = AllianceFramework::get ();
|
|
|
|
RoutingGauge* rg = nw->getKiteEngine()->getRoutingGauge();
|
|
|
|
|
|
|
|
forEach ( Net*, inet, nw->getCell()->getNets() ) {
|
|
|
|
if ( inet->getType() == Net::Type::POWER ) continue;
|
|
|
|
if ( inet->getType() == Net::Type::GROUND ) continue;
|
|
|
|
if ( inet->getType() == Net::Type::CLOCK ) continue;
|
* ./kite:
- Change: Propagate renaming "obstacle" -> "blockage".
- Bug/Change: In Configuration, the value of the extensionCap was too big
(1.5 lambda), reduce to 0.5 lambda. This is a problem, the extension
should be coupled to the layer as it is not the same for each METAL.
- Bug: When using TrackElement, always uses the virtual "->isFixed()" method
instead of trying to access to "->base()->isFixed()" as the base may be
NULL in case of blockage/fixed segment.
- Change: Merge PowerRails & Blockage trans-hierarchical construction (into
PowerRails). All blockages are groupeds under "blockagenet".
Allows to remove TrackBlockage & BuildBlockages.
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
ring power segments around the core must completly saturate the edges
in their segment direction. This is to prevent the global router to
use paths under the power/ground ring (may generate unsolvable configs).
- Change: In KiteEngine::annotateGloblalGraph(), when routing a full chip,
distinguish three areas: the core (65%), the corona (90%) and the pads
(100%). Capacities on the edges are sets accordingly.
- Change: In RoutingEvent, introduce an alternative algorithm for
conflictSolve1, FindPath which try to deduce the breakpoints from a
truly explorated path. Unfortunatly this gives worst results than the
Cs1Candidates method. The why should be investigated as it's a critical
point in the algorithm.
- Change: In Manipulator::ripupPerpandicular(), when a caged perpandicular
is encountered, instead of just "stopping", rip it up and change is
axis hint (actually increase) it's axis hint so it stands a chance to
go outside the track with an obstacle.
- Change: In RoutingEvent/State::slackenTopology(), allow move up of local
segments when they are tightly constrained *and* blocked (cageds).
Partial modification of functions calls from booleans to flags.
- Bug: In NegociateWindow::NegociateOverlapCost, check for fixed segments
before trying to get DataNegociate. The lack of DataNegociate cause the
TrackElement to be discarted. It's a failsafe behavior, but it leads to
overlaps.
- Bug: In ProtectRoutingPad, in Pad Cells only, *do not* protect RoutingPad
to avoid the edge capacity over the pad to decrease to zero. This is
due to unused RoutingPads being accounted as blockages.
2010-12-04 09:25:48 -06:00
|
|
|
if ( af->isBLOCKAGE(inet->getName()) ) continue;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
forEach ( RoutingPad*, irp, inet->getRoutingPads() ) {
|
|
|
|
size_t depth = rg->getLayerDepth(irp->getLayer());
|
|
|
|
if ( depth > 0 ) continue;
|
|
|
|
if ( depth == 0 ) {
|
|
|
|
TrackMarker::create ( *irp, 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // End of local namespace.
|
|
|
|
|
|
|
|
|
|
|
|
namespace Kite {
|
|
|
|
|
|
|
|
using std::cerr;
|
|
|
|
using std::endl;
|
|
|
|
using std::setw;
|
|
|
|
using std::left;
|
|
|
|
using std::right;
|
|
|
|
using std::setprecision;
|
2010-12-12 15:42:57 -06:00
|
|
|
using Hurricane::Warning;
|
2010-03-09 09:24:55 -06:00
|
|
|
using Hurricane::Bug;
|
|
|
|
using Hurricane::tab;
|
|
|
|
using Hurricane::inltrace;
|
|
|
|
using Hurricane::ltracein;
|
|
|
|
using Hurricane::ltraceout;
|
|
|
|
using Hurricane::ForEachIterator;
|
2010-12-15 09:12:00 -06:00
|
|
|
using CRL::Histogram;
|
2010-08-22 07:38:27 -05:00
|
|
|
using CRL::addMeasure;
|
2010-12-12 15:42:57 -06:00
|
|
|
using Katabatic::AutoContact;
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "NegociateWindow".
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
NegociateWindow::NegociateWindow ( KiteEngine* kite )
|
|
|
|
: _slowMotion (0)
|
|
|
|
, _interrupt (false)
|
|
|
|
, _kite (kite)
|
|
|
|
, _gcells ()
|
|
|
|
, _segments ()
|
|
|
|
, _eventQueue ()
|
|
|
|
, _eventHistory()
|
|
|
|
{ }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
NegociateWindow* NegociateWindow::create ( KiteEngine* kite )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
NegociateWindow* negociateWindow = new NegociateWindow ( kite );
|
2010-03-09 09:24:55 -06:00
|
|
|
return negociateWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NegociateWindow::~NegociateWindow ()
|
2010-12-12 15:42:57 -06:00
|
|
|
{ }
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
|
|
|
|
void NegociateWindow::destroy ()
|
|
|
|
{ delete this; }
|
|
|
|
|
|
|
|
|
|
|
|
Cell* NegociateWindow::getCell () const
|
|
|
|
{ return _kite->getCell(); }
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
void NegociateWindow::setGCells ( const Katabatic::GCellVector& gcells )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
_gcells = gcells;
|
|
|
|
//sort ( _gcells.begin(), _gcells.end(), Katabatic::GCell::CompareGCellById() );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
loadRoutingPads ( this );
|
|
|
|
Session::revalidate ();
|
|
|
|
|
|
|
|
TrackElement* segment;
|
|
|
|
TrackElementLut lut = Session::getKiteEngine()->_getTrackElementLut();
|
|
|
|
TrackElementLut::iterator it = lut.begin ();
|
|
|
|
for ( ; it != lut.end() ; it++ ) {
|
|
|
|
segment = it->second;
|
|
|
|
segment->getDataNegociate()->update();
|
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
_statistics.setGCellsCount ( _gcells.size() );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void NegociateWindow::addInsertEvent ( TrackElement* segment, unsigned int level )
|
|
|
|
{
|
|
|
|
DataNegociate* data = segment->getDataNegociate();
|
|
|
|
if ( not data or not data->hasRoutingEvent() )
|
|
|
|
_eventQueue.add ( segment, level );
|
|
|
|
else
|
|
|
|
cerr << Bug("NegociateWidow::addInsertEvent(): Try to adds twice the same TrackElement event."
|
|
|
|
"\n %p:%s."
|
|
|
|
,(void*)segment->base()->base()
|
|
|
|
,getString(segment).c_str()
|
|
|
|
) << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
TrackElement* NegociateWindow::addTrackSegment ( AutoSegment* autoSegment, bool loading )
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
ltrace(200) << "NegociateWindow::addTrackSegment() - " << autoSegment << endl;
|
|
|
|
ltracein(159);
|
|
|
|
|
|
|
|
// Special case: fixed AutoSegments must not interfere with blockages.
|
|
|
|
// Ugly: uses of getExtensionCap().
|
|
|
|
if ( autoSegment->isFixed() ) {
|
|
|
|
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(autoSegment->getLayer());
|
|
|
|
Track* track = plane->getTrackByPosition ( autoSegment->getAxis() );
|
|
|
|
size_t begin;
|
|
|
|
size_t end;
|
|
|
|
Interval fixedSpan;
|
|
|
|
Interval blockageSpan;
|
|
|
|
|
|
|
|
autoSegment->getCanonical ( fixedSpan );
|
|
|
|
fixedSpan.inflate ( Session::getExtensionCap()-1 );
|
|
|
|
|
|
|
|
track->getOverlapBounds ( fixedSpan, begin, end );
|
|
|
|
for ( ; (begin < end) ; begin++ ) {
|
|
|
|
|
|
|
|
TrackElement* other = track->getSegment(begin);
|
|
|
|
ltrace(200) << "| overlap: " << other << endl;
|
|
|
|
|
|
|
|
if ( not other->isBlockage() ) continue;
|
|
|
|
|
|
|
|
other->getCanonical ( blockageSpan );
|
|
|
|
blockageSpan.inflate(Session::getExtensionCap());
|
|
|
|
|
|
|
|
ltrace(200) << " fixed:" << fixedSpan << " vs. blockage:" << blockageSpan << endl;
|
|
|
|
|
|
|
|
if ( not fixedSpan.intersect(blockageSpan) ) continue;
|
|
|
|
|
|
|
|
// Overlap between fixed & blockage.
|
|
|
|
ltrace(200) << "* Blockage overlap: " << autoSegment << endl;
|
|
|
|
Session::destroyRequest ( autoSegment );
|
|
|
|
|
|
|
|
cerr << Warning("Overlap between fixed %s and blockage at %s."
|
|
|
|
,getString(autoSegment).c_str(),getString(blockageSpan).c_str()) << endl;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
Interval span;
|
|
|
|
autoSegment = autoSegment->getCanonical ( span );
|
|
|
|
|
|
|
|
bool created;
|
|
|
|
TrackElement* trackSegment = TrackSegment::create ( autoSegment, NULL, created );
|
|
|
|
|
|
|
|
if ( not loading )
|
|
|
|
ltrace(159) << "* lookup: " << autoSegment << endl;
|
|
|
|
|
|
|
|
if ( created ) {
|
|
|
|
ltrace(159) << "* " << trackSegment << endl;
|
|
|
|
|
|
|
|
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(autoSegment->getLayer());
|
|
|
|
Track* track = plane->getTrackByPosition ( autoSegment->getAxis() );
|
|
|
|
Interval uside = autoSegment->getAutoSource()->getGCell()->getUSide ( Constant::perpandicular(autoSegment->getDirection())/*, false */);
|
|
|
|
|
|
|
|
if ( track->getAxis() > uside.getVMax() ) track = track->getPrevious();
|
|
|
|
if ( track->getAxis() < uside.getVMin() ) track = track->getNext();
|
|
|
|
|
|
|
|
trackSegment->setAxis ( track->getAxis(), Katabatic::Realignate|Katabatic::AxisSet );
|
|
|
|
trackSegment->invalidate ();
|
|
|
|
|
|
|
|
if ( trackSegment->isFixed() ) {
|
|
|
|
Session::addInsertEvent ( trackSegment, track );
|
|
|
|
} else {
|
|
|
|
_segments.push_back ( trackSegment );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( not created and not loading ) {
|
|
|
|
ltrace(200) << "TrackSegment already exists (and not in loading stage)." << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
ltraceout(159);
|
|
|
|
|
|
|
|
return trackSegment;
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
double NegociateWindow::computeWirelength ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
set<TrackElement*> accounteds;
|
|
|
|
double totalWL = 0.0;
|
|
|
|
|
|
|
|
for ( size_t igcell=0 ; igcell<_gcells.size() ; ++igcell ) {
|
|
|
|
double gcellWL = 0.0;
|
|
|
|
Segment* segment;
|
|
|
|
TrackElement* trackSegment;
|
|
|
|
|
|
|
|
vector<AutoContact*>* contacts = _gcells[igcell]->getContacts();
|
|
|
|
for ( size_t i=0 ; i<contacts->size() ; i++ ) {
|
|
|
|
forEach ( Hook*, ihook, (*contacts)[i]->getBodyHook()->getSlaveHooks() ) {
|
|
|
|
Hook* sourceHook = dynamic_cast<Segment::SourceHook*>(*ihook);
|
|
|
|
if ( not sourceHook ) continue;
|
|
|
|
|
|
|
|
segment = dynamic_cast<Segment*>(sourceHook->getComponent());
|
|
|
|
trackSegment = Session::lookup ( segment );
|
|
|
|
if ( trackSegment ) {
|
|
|
|
if ( accounteds.find(trackSegment) != accounteds.end() ) continue;
|
|
|
|
|
|
|
|
accounteds.insert ( trackSegment );
|
|
|
|
gcellWL += DbU::getLambda ( trackSegment->getLength() );
|
|
|
|
}
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
// Partial sum to limit rounding errors.
|
|
|
|
totalWL += gcellWL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return totalWL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void NegociateWindow::_createRouting ( Katabatic::GCell* gcell )
|
|
|
|
{
|
|
|
|
ltrace(200) << "NegociateWindow::_createRouting() - " << gcell << endl;
|
|
|
|
ltracein(200);
|
|
|
|
|
|
|
|
Segment* segment;
|
|
|
|
AutoSegment* autoSegment;
|
|
|
|
|
|
|
|
ltrace(149) << "AutoSegments from AutoContacts" << endl;
|
|
|
|
vector<AutoContact*>* contacts = gcell->getContacts();
|
|
|
|
for ( size_t i=0 ; i<contacts->size() ; i++ ) {
|
|
|
|
forEach ( Component*, component, (*contacts)[i]->getSlaveComponents() ) {
|
|
|
|
segment = dynamic_cast<Segment*>(*component);
|
|
|
|
autoSegment = Session::base()->lookup ( segment );
|
|
|
|
ltrace(149) << autoSegment << endl;
|
|
|
|
if ( autoSegment and autoSegment->isCanonical() ) {
|
|
|
|
addTrackSegment ( autoSegment, true );
|
|
|
|
}
|
|
|
|
}
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
2010-12-12 15:42:57 -06:00
|
|
|
|
|
|
|
ltrace(149) << "_segments.size():" << _segments.size() << endl;
|
|
|
|
ltraceout(200);
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
size_t NegociateWindow::_negociate ()
|
2010-03-09 09:24:55 -06:00
|
|
|
{
|
2010-12-12 15:42:57 -06:00
|
|
|
ltrace(150) << "NegociateWindow::_negociate() - " << _segments.size() << endl;
|
2010-03-09 09:24:55 -06:00
|
|
|
ltracein(149);
|
|
|
|
|
2010-04-23 08:14:17 -05:00
|
|
|
unsigned long limit = _kite->getEventsLimit();
|
|
|
|
|
2010-03-09 09:24:55 -06:00
|
|
|
_eventHistory.clear();
|
2010-12-12 15:42:57 -06:00
|
|
|
_eventQueue.load ( _segments );
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
size_t count = 0;
|
|
|
|
while ( not _eventQueue.empty() and not isInterrupted() ) {
|
|
|
|
RoutingEvent* event = _eventQueue.pop ();
|
|
|
|
|
|
|
|
event->process ( _eventQueue, _eventHistory );
|
|
|
|
if (tty::enabled()) {
|
2010-12-12 15:42:57 -06:00
|
|
|
cmess1 << " <event:" << tty::bold << setw(7) << setfill('0')
|
2010-03-09 09:24:55 -06:00
|
|
|
<< RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
|
|
|
|
cmess1.flush ();
|
|
|
|
} else {
|
2010-12-12 15:42:57 -06:00
|
|
|
cmess2 << " <event:" << setw(7) << setfill('0')
|
2010-04-12 06:24:57 -05:00
|
|
|
<< RoutingEvent::getProcesseds() << setfill(' ') << "> id:"
|
|
|
|
<< event->getSegment()->getId() << " "
|
2010-03-09 09:24:55 -06:00
|
|
|
<< event->getSegment()->getNet()->getName()
|
|
|
|
<< endl;
|
|
|
|
cmess2.flush();
|
|
|
|
}
|
|
|
|
|
2010-04-23 08:14:17 -05:00
|
|
|
if ( RoutingEvent::getProcesseds() >= limit ) setInterrupt ( true );
|
2010-03-09 09:24:55 -06:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
if (count and tty::enabled()) cmess1 << endl;
|
|
|
|
count = 0;
|
|
|
|
|
|
|
|
ltrace(200) << "Dumping history." << endl;
|
2010-05-03 04:16:50 -05:00
|
|
|
for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) {
|
2010-03-09 09:24:55 -06:00
|
|
|
RoutingEvent* event = _eventHistory.getNth(i);
|
|
|
|
ltrace(200) << (void*)event << " ["
|
|
|
|
<< (event->isCloned ()?"C":"-")
|
|
|
|
<< (event->isDisabled ()?"d":"-")
|
|
|
|
<< (event->isUnimplemented()?"u":"-") << "] "
|
|
|
|
<< event->getSegment() << endl;
|
|
|
|
if ( !event->isCloned() and event->isUnimplemented() ) {
|
|
|
|
count++;
|
|
|
|
event->setProcessed ( false );
|
|
|
|
event->setMode ( RoutingEvent::PostPack );
|
|
|
|
event->process ( _eventQueue, _eventHistory );
|
|
|
|
|
|
|
|
if (tty::enabled()) {
|
2010-12-12 15:42:57 -06:00
|
|
|
cmess1 << " <event:"
|
2010-03-26 13:03:01 -05:00
|
|
|
<< tty::bold << tty::fgcolor(tty::Red) << setw(7) << setfill('0')
|
2010-03-09 09:24:55 -06:00
|
|
|
<< RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
|
|
|
|
cmess1.flush ();
|
|
|
|
} else {
|
2010-12-12 15:42:57 -06:00
|
|
|
cmess1 << " <event:" << setw(7) << setfill('0')
|
2010-03-09 09:24:55 -06:00
|
|
|
<< RoutingEvent::getProcesseds() << setfill(' ') << ">" << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (count and tty::enabled()) cmess1 << endl;
|
|
|
|
|
|
|
|
size_t eventsCount = _eventHistory.size();
|
|
|
|
|
|
|
|
_eventHistory.clear();
|
|
|
|
_eventQueue.clear();
|
|
|
|
|
|
|
|
if ( RoutingEvent::getAllocateds() > 0 ) {
|
|
|
|
cerr << Bug("%d events remains after clear.",RoutingEvent::getAllocateds()) << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if ( _slowMotion && getCellWidget() ) {
|
|
|
|
// Session::close ();
|
|
|
|
// getCellWidget()->refresh();
|
|
|
|
// Session::open ( _kiteEngine );
|
|
|
|
// }
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
_statistics.setEventsCount ( eventsCount );
|
2010-03-09 09:24:55 -06:00
|
|
|
ltraceout(149);
|
|
|
|
|
|
|
|
return eventsCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void NegociateWindow::run ( int slowMotion )
|
|
|
|
{
|
|
|
|
ltrace(150) << "NegociateWindow::run()" << endl;
|
|
|
|
ltracein(149);
|
|
|
|
|
|
|
|
TrackElement::setOverlapCostCB ( NegociateOverlapCost );
|
|
|
|
RoutingEvent::resetProcesseds ();
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
for ( size_t igcell=0 ; igcell<_gcells.size() ; ++igcell ) {
|
|
|
|
_createRouting ( _gcells[igcell] );
|
|
|
|
}
|
|
|
|
Session::revalidate ();
|
|
|
|
|
|
|
|
getKiteEngine()->setMinimumWL ( computeWirelength() );
|
|
|
|
|
|
|
|
#if defined(CHECK_DATABASE)
|
|
|
|
unsigned int overlaps = 0;
|
|
|
|
Session::getKiteEngine()->_check(overlaps,"after _createRouting(GCell*)");
|
|
|
|
#endif
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
_slowMotion = slowMotion;
|
2010-12-12 15:42:57 -06:00
|
|
|
_negociate ();
|
2010-03-09 09:24:55 -06:00
|
|
|
|
|
|
|
Session::get()->isEmpty();
|
|
|
|
|
|
|
|
# if defined(CHECK_DATABASE)
|
|
|
|
_kite->_check ( overlaps, "after negociation" );
|
|
|
|
# endif
|
|
|
|
|
|
|
|
ltraceout(149);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void NegociateWindow::printStatistics () const
|
|
|
|
{
|
2010-06-22 08:59:22 -05:00
|
|
|
cmess1 << " o Computing statistics." << endl;
|
|
|
|
cmess1 << Dots::asSizet(" - Processeds Events Total",RoutingEvent::getProcesseds()) << endl;
|
|
|
|
cmess1 << Dots::asSizet(" - Unique Events Total"
|
|
|
|
,(RoutingEvent::getProcesseds() - RoutingEvent::getCloneds())) << endl;
|
2010-12-12 15:42:57 -06:00
|
|
|
cmess1 << Dots::asSizet(" - # of GCells",_statistics.getGCellsCount()) << endl;
|
2010-08-22 07:38:27 -05:00
|
|
|
|
|
|
|
addMeasure<size_t>( getCell(), "Events" , RoutingEvent::getProcesseds(), 12 );
|
|
|
|
addMeasure<size_t>( getCell(), "UEvents", RoutingEvent::getProcesseds()-RoutingEvent::getCloneds(), 12 );
|
2010-12-12 15:42:57 -06:00
|
|
|
|
2010-12-15 09:12:00 -06:00
|
|
|
Histogram* densityHistogram = new Histogram ( 1.0, 0.1, 2 );
|
|
|
|
addMeasure<Histogram>( getCell(), "GCells Density Histogram", densityHistogram );
|
|
|
|
|
|
|
|
densityHistogram->setFileExtension ( ".density.histogram" );
|
|
|
|
densityHistogram->setMainTitle ( "GCell Densities" );
|
|
|
|
densityHistogram->setTitle ( "Avg. Density", 0 );
|
|
|
|
densityHistogram->setTitle ( "Peak Density", 1 );
|
|
|
|
densityHistogram->setColor ( "green", 0 );
|
|
|
|
densityHistogram->setColor ( "red" , 1 );
|
2010-12-12 15:42:57 -06:00
|
|
|
|
|
|
|
const Katabatic::GCellVector* gcells = getKiteEngine()->getGCellGrid()->getGCellVector();
|
|
|
|
|
|
|
|
getKiteEngine()->getGCellGrid()->setDensityMode ( Katabatic::GCellGrid::AverageHVDensity );
|
|
|
|
for ( size_t igcell=0 ; igcell<(*gcells).size() ; ++igcell ) {
|
2010-12-15 09:12:00 -06:00
|
|
|
densityHistogram->addSample ( (*gcells)[igcell]->getDensity(), 0 );
|
2010-12-12 15:42:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
getKiteEngine()->getGCellGrid()->setDensityMode ( Katabatic::GCellGrid::MaxDensity );
|
|
|
|
for ( size_t igcell=0 ; igcell<(*gcells).size() ; ++igcell ) {
|
2010-12-15 09:12:00 -06:00
|
|
|
densityHistogram->addSample ( (*gcells)[igcell]->getDensity(), 1 );
|
2010-12-12 15:42:57 -06:00
|
|
|
}
|
|
|
|
|
2010-12-15 09:12:00 -06:00
|
|
|
densityHistogram->normalize ( 0 );
|
|
|
|
densityHistogram->normalize ( 1 );
|
2010-03-09 09:24:55 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string NegociateWindow::_getString () const
|
|
|
|
{
|
|
|
|
ostringstream os;
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
os << "<" << _getTypeName() << ">";
|
2010-03-09 09:24:55 -06:00
|
|
|
return ( os.str() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Record* NegociateWindow::_getRecord () const
|
|
|
|
{
|
|
|
|
Record* record = new Record ( _getString() );
|
|
|
|
|
2010-12-12 15:42:57 -06:00
|
|
|
record->add ( getSlot ( "_gcells", _gcells ) );
|
2010-03-09 09:24:55 -06:00
|
|
|
return ( record );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // End of Kite namespace.
|