* ./kite:

- New: In NegociateWindow/RoutingEvent, adds a more comprehensive stage
        "Repair". Perform in three stage: first try to place with a relaxed
        constraint (one GCell on each side). Second try to minimize the faulty
        segment. Third perform another "repack perpandicular" but this time
        the faulty segment is re-inserted *before* any of it's perpandiculars.
    - New: In RoutingEvent::cacheAxisHint(), when a segment has a parent, that
        is comes for a "moveUp()", uses the parent axis hint as it's own.
    - New: In State::slackenTopology(), in the global FSM, adds a special
        operation when reaching MaximumSlack: forceOverLocals(), try to insert
        the global on track containing only local segments. Should tend to
        concentrate locals on a small set of shared tracks. Most useful on the
        highest layers.
    - New: In State::slackenTopology(), in the "MoveUp" state, try to find the
        more appropriate segment to move up (Manipulator::desaturate()).
        Effectively move up the longest segment fully enclosing the one we are
        processing.
    - New: In State::slackenTopology(), add a check for fully blocked segments
        in the local segment FSM. Calls State::solveFullBlocked().
    - New: In KiteEngine::createGlobalGraph(), decrease the vertical capacity
        of one track inside the core. Helps smooth the vertical density.
    - Change: In Manipulator::insertInTrack(), when a track is freed for a
        to be inserted changes the priorities so that the segment is immediatly
        inserted. Parallels ripeds and theirs perpandiculars are replaced
        only *after*. This is the opposite of the previous behavior.
    - Change: In NegociateWindow::NegociateOverlapCost(), account the costs
        of terminals only for deep depth layers (M1, M2 & M3).
    - Change: In RoutingEvent::insertInTrack(), expand the excluded interval
        by a half-pitch (2.5l) instead of one lambda.
    - Change: In State::State(), do not uses DiscardGlobal if the ripup count
        exceed 5. Case of the "Strap" segments that can be ripped a lot
        before changing state.
    - Change: In State::_processNegociate(), no longer lock into position
        (fixed) the local terminal segments as a last resort.
    - Change: In RoutingEvent::_processNegociate(), no longer ripup perpandiculars
        when a segment is inserted in a free space. Reduce the number of
        events whithout degrading the routing quality.
    - Change: In State::conflictSolve1_v1b(), if getLongestConflict() is nul,
        ignore the track, the conflict must occurs on another track.
    - Change: In TrackCost, add a flag support. First uses, a flags to prevent
        a local of the topmost layer to ripup a global which is in moveUp
        state.
    - Bug: In State::solveFullBlockage(), after have been freed, reset the
        segment state to "moveUp".
    - Bug: In manipulator::minimize(), the axisHint was miscalculated if the
        punctual span was empty.
This commit is contained in:
Jean-Paul Chaput 2011-01-25 17:16:50 +00:00
parent cbccf9e2a4
commit 17f3207d71
15 changed files with 661 additions and 265 deletions

View File

@ -93,6 +93,7 @@ namespace Kite {
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;
}

View File

@ -269,6 +269,7 @@ namespace Kite {
forEach ( Knik::Vertex*, ivertex, _knik->getRoutingGraph()->getVertexes() ) {
for ( int i=0 ; i<2 ; ++i ) {
Knik::Edge* edge = NULL;
bool isVEdge = false;
if ( i==0 ) {
edge = ivertex->getHEdgeOut();
@ -278,6 +279,7 @@ namespace Kite {
edge->setCapacity ( 0 );
continue;
}
isVEdge = false;
} else {
edge = ivertex->getVEdgeOut();
if ( not edge ) continue;
@ -286,13 +288,18 @@ namespace Kite {
edge->setCapacity ( 0 );
continue;
}
isVEdge = true;
}
float edgePercent = 1.00;
if ( chipTools.getCorona().getInnerBox().contains(edge->getBoundingBox()) ) edgePercent = corePercent;
else if ( chipTools.getCorona().getOuterBox().contains(edge->getBoundingBox()) ) edgePercent = coronaPercent;
if ( chipTools.getCorona().getInnerBox().contains(edge->getBoundingBox()) ) {
edgePercent = corePercent;
} else if ( chipTools.getCorona().getOuterBox().contains(edge->getBoundingBox()) ) {
edgePercent = coronaPercent;
isVEdge = false;
}
unsigned int capacity = (unsigned int)(edge->getCapacity() * edgePercent );
unsigned int capacity = (unsigned int)(edge->getCapacity() * edgePercent ) - ((isVEdge) ? 1 : 0);
edge->setCapacity ( capacity );
}
}
@ -460,13 +467,18 @@ namespace Kite {
//DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_re(20)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_addsub32_carith_se_gi_1_29" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instaddbracry_sd.gi_1_29" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.pi_2_26" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.pi_2_18" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.gi_0_18" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.gi_2_18" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.gi_1_17" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_se(28)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.etat32_otheri_sd_2.enx" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.yoper_se(31)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.toper_se(5)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.toper_rd(24)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.soper_se(20)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.shift32_rshift_se.muxoutput(68)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.shift32_rshift_se.muxoutput(67)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.shift32_rshift_se.muxoutput(71)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.imdsgn_sd0" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.res_re(12)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.res_re(20)" );
@ -479,40 +491,53 @@ namespace Kite {
//DebugSession::addToTrace ( getCell(), "d_out_i(19)" );
//DebugSession::addToTrace ( getCell(), "dout_e_i(1)" );
//DebugSession::addToTrace ( getCell(), "dout_e_i(2)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.aux178" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.aux78" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.nxr2_x1_2_sig" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.na4_x1_23_sig" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.ao22_x2_38_sig" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.rsdnbr_sd(14)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.ao22_x2_sig" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.rsdnbr_sd(25)" );
//DebugSession::addToTrace ( getCell(), "d_out_i(28)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_1m_ct_mbk_buf_opcod_sd_0" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.break_re" );
//DebugSession::addToTrace ( getCell(), "d_atype_i(0)" );
//DebugSession::addToTrace ( getCell(), "addr_i(7)" );
//DebugSession::addToTrace ( getCell(), "addr_i(8)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_sd_5" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.break_re" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_sd_2" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_sd_1" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_rd(1)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.i_write_sm" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_i_ri(29)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_rd(0)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_sd_3" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_sd_5" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.no4_x1_7_sig" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.on12_x1_15_sig" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.na3_x1_46_sig" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.o2_x2_11_sig" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.nextsr_rx(27)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_wsr_sm" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.i_ri(5)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_aux144" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_aux143" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.aux71" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_aux61" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.aux4" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_hold_si" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_i_ri(30)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.data_rm(0)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.toper_se(0)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.res_se(17)" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_0_20" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_2_22" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_2_23" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_2_23" );
//DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_1_21" );
// DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_4_24" );
// DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_4_28" );
// DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_1_25" );
// //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_2_23" );
// //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_0_28" );
// // NO MOVE UP FOR IT...
// DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_3_23" );
// DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_3_28" );
createDetailedGrid ();
buildPowerRails ();
@ -552,8 +577,6 @@ namespace Kite {
Session::open ( this );
cmess1 << " o Running Negociate Algorithm" << endl;
_negociateWindow = NegociateWindow::create ( this );
_negociateWindow->setGCells ( *(getGCellGrid()->getGCellVector()) );
preProcess ();
@ -629,9 +652,9 @@ namespace Kite {
float expandRatio = 1.0;
if ( _minimumWL != 0.0 ) {
expandRatio = totalWireLength / _minimumWL;
expandRatio = ((totalWireLength-_minimumWL) / _minimumWL) * 100.0;
cmess1 << " - Wire Length Expand Ratio := "
<< setprecision(4) << expandRatio
<< setprecision(3) << expandRatio
<< "% [min:" << setprecision(9) << _minimumWL << "] "
<< endl;
}

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved
//
// ===================================================================
//
@ -65,7 +65,7 @@ namespace {
{
Interval intersect = segment->getCanonicalInterval();
if ( not intersect.intersect ( cost.getInterval() ) ) return;
if ( not intersect.intersect(cost.getInterval()) ) return;
if ( segment->isBlockage() or segment->isFixed() ) {
ltrace(200) << "Infinite cost from: " << segment << endl;
@ -76,12 +76,18 @@ namespace {
return;
}
if ( cost.getInterval().getVMax() > intersect.getVMax() ) cost.setLeftOverlap();
if ( cost.getInterval().getVMin() < intersect.getVMin() ) cost.setRightOverlap();
//cost.setLonguestOverlap ( intersect.getSize() );
//intersect.intersection ( cost.getInterval() );
if ( not intersect.contains(cost.getInterval()) )
intersect.intersection ( cost.getInterval() );
else {
cost.setLonguestOverlap ( intersect.getSize() );
cost.setGlobalEnclosed ();
}
DataNegociate* data = segment->getDataNegociate ();
if ( not data ) return;
@ -98,6 +104,13 @@ namespace {
//if ( data->getState() >= DataNegociate::ConflictSolve1 ) {
cost.setOverlapGlobal();
//}
if ( (cost.getFlags() & TrackCost::LocalAndTopDepth)
and (data->getState() >= DataNegociate::MoveUp) ) {
cost.setInfinite ();
cost.setOverlap ();
cost.setHardOverlap ();
return;
}
}
// if ( data->getRipupCount() > 3 ) {
@ -112,6 +125,8 @@ namespace {
cost.setOverlap ();
if ( segment->isLocal() or (Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) < 3) )
cost.incTerminals ( data->getCost().getTerminals()*100 );
ltrace(200) << "| Increment Delta: " << DbU::getValueString(intersect.getSize()) << endl;
cost.incDelta ( intersect.getSize() );
}
@ -132,6 +147,7 @@ namespace {
if ( depth > 0 ) continue;
if ( depth == 0 ) {
TrackMarker::create ( *irp, 1 );
//TrackMarker::create ( *irp, 2 );
}
}
}
@ -379,12 +395,16 @@ namespace Kite {
ltrace(150) << "NegociateWindow::_negociate() - " << _segments.size() << endl;
ltracein(149);
cmess1 << " o Negociation Stage." << endl;
unsigned long limit = _kite->getEventsLimit();
//unsigned long limit = 25586;
_eventHistory.clear();
_eventQueue.load ( _segments );
size_t count = 0;
RoutingEvent::setStage ( RoutingEvent::Negociate );
while ( not _eventQueue.empty() and not isInterrupted() ) {
RoutingEvent* event = _eventQueue.pop ();
@ -406,37 +426,73 @@ namespace Kite {
event->process ( _eventQueue, _eventHistory, _eventLoop );
if ( RoutingEvent::getProcesseds() >= limit ) setInterrupt ( true );
count++;
if ( RoutingEvent::getProcesseds() >= limit ) setInterrupt ( true );
}
if (count and tty::enabled()) cmess1 << endl;
count = 0;
ltrace(200) << "Dumping history." << endl;
cmess1 << " o Repair Stage." << endl;
ltrace(200) << "Loadind Repair queue." << endl;
RoutingEvent::setStage ( RoutingEvent::Repair );
for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) {
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, _eventLoop );
if ( not event->isCloned() and event->isUnimplemented() ) {
event->reschedule ( _eventQueue, 0 );
}
}
_eventQueue.commit ();
count = 0;
while ( not _eventQueue.empty() and not isInterrupted() ) {
RoutingEvent* event = _eventQueue.pop ();
if (tty::enabled()) {
cmess1 << " <event:"
<< tty::bold << tty::fgcolor(tty::Red) << setw(7) << setfill('0')
cmess2 << " <repair.event:" << tty::bold << setw(7) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
cmess1.flush ();
cmess2.flush ();
} else {
cmess1 << " <event:" << setw(7) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << ">" << endl;
}
cmess2 << " <repair.event:" << setw(7) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << " "
<< event->getEventLevel() << ":" << event->getPriority() << "> "
<< event->getSegment()
//<< "> @" << DbU::getValueString(event->getSegment()->getAxis())
//<< " id:" << event->getSegment()->getId()
//<< " " << event->getSegment()->getNet()->getName()
<< endl;
cmess2.flush();
}
event->process ( _eventQueue, _eventHistory, _eventLoop );
count++;
if ( RoutingEvent::getProcesseds() >= limit ) setInterrupt ( true );
}
// {
// ltrace(200) << (void*)event << " ["
// << (event->isCloned ()?"C":"-")
// << (event->isDisabled ()?"d":"-")
// << (event->isUnimplemented()?"u":"-") << "] "
// << event->getSegment() << endl;
// if ( not event->isCloned() and event->isUnimplemented() ) {
// count++;
// event->setProcessed ( false );
// event->setMode ( RoutingEvent::Repair );
// event->process ( _eventQueue, _eventHistory, _eventLoop );
// if (tty::enabled()) {
// cmess1 << " <event:"
// << tty::bold << tty::fgcolor(tty::Red) << setw(7) << setfill('0')
// << RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
// cmess1.flush ();
// } else {
// cmess1 << " <event:" << setw(7) << setfill('0')
// << RoutingEvent::getProcesseds() << setfill(' ') << ">" << endl;
// }
// }
// }
if (count and tty::enabled()) cmess1 << endl;
size_t eventsCount = _eventHistory.size();
@ -466,6 +522,8 @@ namespace Kite {
ltrace(150) << "NegociateWindow::run()" << endl;
ltracein(149);
cmess1 << " o Running Negociate Algorithm" << endl;
TrackElement::setOverlapCostCB ( NegociateOverlapCost );
RoutingEvent::resetProcesseds ();

View File

@ -2,13 +2,13 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved
//
// ===================================================================
//
// $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 |
@ -20,7 +20,7 @@
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
#include <cstdlib>
@ -784,16 +784,18 @@ namespace {
// "_immediate" ripup flags was associated with "perpandicular", as they
// must be re-inserted *before* any parallel. Must look to solve the redundancy.
DebugSession::open ( _segment->getNet(), 200 );
if ( _type & Perpandicular ) {
ltrace(200) << "* Riping Pp " << _segment << endl;
} else {
ltrace(200) << "* Riping // " << _segment << endl;
}
if ( _segment->isFixed() ) return true;
if ( _segment->isFixed() ) { DebugSession::close(); return true; }
DataNegociate* data = _segment->getDataNegociate();
if ( data == NULL ) return true;
if ( data == NULL ) { DebugSession::close(); return true; }
if ( _type & ResetRipup ) data->resetRipupCount ();
@ -808,6 +810,7 @@ namespace {
if ( event == NULL ) {
cerr << Bug("Missing Event on %p:%s"
,_segment->base()->base(),getString(_segment).c_str()) << endl;
DebugSession::close();
return true;
}
@ -832,9 +835,14 @@ namespace {
RoutingEvent* fork = event->reschedule ( queue, eventLevel );
if ( fork )
fork->setMode ( (_type&PackingMode) ? RoutingEvent::Pack : RoutingEvent::Negociate );
if ( fork ) {
unsigned int mode = RoutingEvent::Repair;
if ( RoutingEvent::getStage() < RoutingEvent::Repair )
mode = (_type&PackingMode) ? RoutingEvent::Pack : RoutingEvent::Negociate;
fork->setMode ( mode );
}
DebugSession::close ();
return true;
}
@ -950,6 +958,7 @@ namespace {
, DbU::Unit axisHint=0
);
bool ripupPerpandiculars ( unsigned int flags=0 );
void repackPerpandiculars ();
bool ripple ();
bool goOutsideGCell ();
bool minimize ();
@ -970,6 +979,7 @@ namespace {
, DbU::Unit rightAxisHint=0
);
bool forceToTrack ( size_t );
bool forceOverLocals ();
void reprocessPerpandiculars ();
private:
TrackElement* _segment;
@ -1048,7 +1058,10 @@ namespace {
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer());
forEach ( Track*, itrack, Tracks_Range::get(plane,_constraint)) {
_costs.push_back ( itrack->getOverlapCost(segment) );
unsigned int costflags = 0;
costflags |= (segment->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0;
_costs.push_back ( itrack->getOverlapCost(segment,costflags) );
_costs.back().setAxisWeight ( _event->getAxisWeight(itrack->getAxis()) );
_costs.back().incDeltaPerpand ( _data->getCost().getWiringDelta(itrack->getAxis()) );
@ -1072,7 +1085,7 @@ namespace {
Track* nearest = plane->getTrackByPosition(_constraint.getCenter());
if ( (nearest->getAxis() < _constraint.getVMin())
|| (nearest->getAxis() > _constraint.getVMax()) ) {
or (nearest->getAxis() > _constraint.getVMax()) ) {
//setUnimplemented ();
//cerr << "[UNIMPLEMENTED] " << segment << " no Track in constraint interval "
// << _constraint << " " << "." << endl;
@ -1087,8 +1100,15 @@ namespace {
unsigned int flags = 0;
flags |= (segment->isStrap()) ? TrackCost::IgnoreAxisWeight : 0;
flags |= (segment->isLocal() and (_data->getState() < DataNegociate::Minimize))
flags |= (segment->isLocal()
and (_data->getState() < DataNegociate::Minimize)
and (_data->getRipupCount() < 5))
? TrackCost::DiscardGlobals : 0;
flags |= (RoutingEvent::getStage() == RoutingEvent::Repair) ? TrackCost::IgnoreSharedLength : 0;
if ( flags & TrackCost::DiscardGlobals ) {
ltrace(200) << "TrackCost::Compare() - DiscardGlobals" << endl;
}
sort ( _costs.begin(), _costs.end(), TrackCost::Compare(flags) );
@ -1146,9 +1166,11 @@ namespace {
if ( (_actions[i].getType() & SegmentAction::SelfInsert) and ripupOthersParallel )
_actions[i].setFlag ( SegmentAction::EventLevel3 );
DebugSession::open ( _actions[i].getSegment()->getNet(), 200 );
if ( not _actions[i].doAction(_queue) ) {
cinfo << "[INFO] Failed action on " << _actions[i].getSegment() << endl;
}
DebugSession::close ();
}
_actions.clear ();
@ -1562,7 +1584,7 @@ namespace {
}
otherNet = other->getNet();
otherOverlap = other->getCanonicalInterval();
otherIsGlobal = otherIsGlobal or other->isGlobal();
otherIsGlobal = other->isGlobal();
} else {
otherOverlap.merge(other->getCanonicalInterval());
otherIsGlobal = otherIsGlobal or other->isGlobal();
@ -1589,6 +1611,11 @@ namespace {
Interval overlap0 = candidates[icandidate].getLongestConflict();
ltrace(200) << "overlap0: " << overlap0 << endl;
if ( overlap0.isEmpty() ) {
ltrace(200) << "overlap0 is empty, no conflict, ignoring Track candidate." << endl;
continue;
}
Track* track = candidates[icandidate].getTrack();
TrackElement* other = track->getSegment(overlap.getCenter());
if ( not other ) {
@ -1676,50 +1703,102 @@ namespace {
bool State::desaturate ()
{
ltrace(200) << "State::desaturate()" << endl;
ltracein(200);
TrackElement* segment = _event->getSegment();
size_t itrack = 0;
for ( ; itrack<getCosts().size() ; ++itrack ) {
ltrace(200) << "Trying track:" << itrack << endl;
if ( getCost(itrack).isGlobalEnclosed() ) {
Track* track = getTrack(itrack);
size_t begin = getBegin(itrack);
size_t end = getEnd (itrack);
Net* ownerNet = segment->getNet();
Interval toFree (segment->getCanonicalInterval());
bool success = true;
for ( size_t i = begin ; success and (i < end) ; i++ ) {
TrackElement* segment2 = track->getSegment(i);
ltrace(200) << "* Looking // " << segment2 << endl;
if ( segment2->getNet() == ownerNet ) continue;
if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue;
if ( segment2->isFixed() or not segment2->isBipoint() ) {
success = false;
continue;
}
DataNegociate* data2 = segment2->getDataNegociate();
if ( not data2 ) {
ltrace(200) << "No DataNegociate, ignoring." << endl;
success = false;
continue;
}
ltrace(200) << "- Forced moveUp " << segment2 << endl;
if ( not (success=Manipulator(segment2,*this).moveUp(Manipulator::AllowTerminalMoveUp)) ) {
continue;
}
}
if ( success ) {
setState ( State::OtherRipup );
addAction ( segment, SegmentAction::SelfInsert );
segment->setAxis ( getCost(itrack).getTrack()->getAxis() );
break;
}
}
}
ltraceout(200);
return (itrack < _costs.size());
#if DESATURATE_V1
TrackElement* segment = _event->getSegment();
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
ltrace(200) << "State::desaturate()" << segment << endl;
ltracein(200);
if ( segment->getLength() > DbU::lambda(75.0) ) {
ltraceout(200);
return false;
}
// if ( segment->getLength() > DbU::lambda(75.0) ) {
// ltraceout(200);
// return false;
// }
GCell* gcell = segment->base()->getAutoSource()->getGCell();
const vector<AutoSegment*>* globals = (segment->isHorizontal())
? gcell->getHSegments() : gcell->getVSegments();
vector<GCell*> gcells;
segment->getGCells ( gcells );
ltrace(200) << gcell << endl;
if ( (*globals).empty() ) {
ltraceout(200);
return false;
}
for ( size_t i=0 ; i<(*globals).size() ; ++i ) {
size_t gdepth = Session::getRoutingGauge()->getLayerDepth((*globals)[i]->getLayer());
AutoSegment::DepthLengthSet globals;
for ( size_t i=0 ; i<gcells.size() ; ++i ) {
const vector<AutoSegment*>* gcellGlobals = (segment->isHorizontal())
? gcells[i]->getHSegments() : gcells[i]->getVSegments();
for ( size_t i=0 ; i<(*gcellGlobals).size() ; ++i ) {
size_t gdepth = Session::getRoutingGauge()->getLayerDepth((*gcellGlobals)[i]->getLayer());
if ( gdepth != depth ) continue;
if ( (*gcellGlobals)[i] == segment->base() ) continue;
ltrace(200) << "| " << (*globals)[i] << endl;
globals.insert ( (*gcellGlobals)[i] );
}
}
TrackElement* gsegment = Session::lookup ( (*globals)[i] );
ltrace(200) << "|*" << (*globals)[i] << endl;
AutoSegment::DepthLengthSet::iterator iglobal = globals.begin();
for ( ; iglobal != globals.end() ; ++iglobal ) {
TrackElement* gsegment = Session::lookup ( *iglobal );
ltrace(200) << "| " << gsegment << endl;
if ( (*globals)[i] == segment->base() ) continue;
if ( gsegment ) {
if ( Manipulator(gsegment,*this).moveUp() ) {
ltrace(200) << "Successful desaturation of " << gcell << endl;
ltraceout(200);
return true;
}
}
}
ltraceout(200);
return false;
#endif // DESTURATE_V1
}
bool State::slackenTopology ( unsigned int flags )
@ -1785,6 +1864,10 @@ namespace {
success = Manipulator(segment,*this).desalignate();
break;
case DataNegociate::Minimize:
if ( isFullBlocked() ) {
nextState = DataNegociate::Unimplemented;
break;
}
nextState = DataNegociate::DogLeg;
success = Manipulator(segment,*this).minimize();
if ( success ) break;
@ -1830,7 +1913,7 @@ namespace {
and (nextState == DataNegociate::Unimplemented)
and segment->isSlackened()
and isFullBlocked() ) {
solveFullBlockages ();
if ( solveFullBlockages () ) nextState = DataNegociate::MoveUp;
}
} else {
// Global TrackElement State Machine.
@ -1850,15 +1933,15 @@ namespace {
case DataNegociate::Desalignate:
ltrace(200) << "Global, State: Minimize, DogLeg or Desalignate." << endl;
if ( (success = Manipulator(segment,*this).desalignate()) ) {
nextState = DataNegociate::Slacken;
break;
}
nextState = DataNegociate::Slacken;
case DataNegociate::Slacken:
ltrace(200) << "Global, State: Slacken." << endl;
if ( (success = Manipulator(segment,*this).slacken()) ) {
nextState = DataNegociate::MoveUp;
break;
}
nextState = DataNegociate::MoveUp;
case DataNegociate::MoveUp:
ltrace(200) << "Global, State: MoveUp." << endl;
//if ( (success = desaturate()) ) break;
@ -1884,6 +1967,9 @@ namespace {
}
}
case DataNegociate::MaximumSlack:
if ( (success=Manipulator(segment,*this).forceOverLocals()) ) {
break;
}
case DataNegociate::Unimplemented:
ltrace(200) << "Global, State: MaximumSlack or Unimplemented." << endl;
nextState = DataNegociate::Unimplemented;
@ -1899,7 +1985,7 @@ namespace {
if ( not success
and (nextState == DataNegociate::Unimplemented)
and segment->isSlackened() ) {
solveFullBlockages ();
if ( solveFullBlockages() ) nextState = DataNegociate::MoveUp;
}
}
}
@ -2575,12 +2661,12 @@ namespace {
}
}
if ( not (shrinkLeft xor shrinkRight) ) {
//if ( not (shrinkLeft xor shrinkRight) ) {
ltrace(200) << "- Hard overlap/enclosure/shrink " << segment2 << endl;
if ( _segment->isStrap() and segment2->isGlobal() ) continue;
if ( not (success = Manipulator(segment2,_S).ripup(toFree,SegmentAction::OtherRipup)) )
continue;
}
//}
canonicals.clear ();
forEach ( TrackElement*, isegment3
@ -2603,7 +2689,7 @@ namespace {
if ( not (success=Manipulator(*isegment3,_S).ripup ( track->getAxis()
, SegmentAction::OtherPushAside
| SegmentAction::AxisHint
, toFree.getVMin() - DbU::lambda(1.0)
, toFree.getVMin() - DbU::lambda(2.5)
)) )
break;
@ -2619,7 +2705,7 @@ namespace {
if ( not (success=Manipulator(*isegment3,_S).ripup ( track->getAxis()
, SegmentAction::OtherPushAside
| SegmentAction::AxisHint
, toFree.getVMax() + DbU::lambda(1.0)
, toFree.getVMax() + DbU::lambda(2.5)
)) )
break;
if ( event3->getTracksFree() == 1 ) {
@ -2646,8 +2732,10 @@ namespace {
}
if ( success ) {
ltrace(200) << "Manipulator::insertInTrack() success" << endl;
_S.setState ( State::OtherRipup );
_S.addAction ( _segment, SegmentAction::SelfInsert /*| SegmentAction::EventLevel3*/ );
_S.addAction ( _segment, SegmentAction::SelfInsert|SegmentAction::EventLevel4 );
_segment->setAxis ( _S.getCost(itrack).getTrack()->getAxis() );
unsigned int flags = 0;
@ -2795,6 +2883,67 @@ namespace {
}
bool Manipulator::forceOverLocals ()
{
ltrace(200) << "Manipulator::forceOverLocals()" << endl;
ltracein(200);
vector<TrackCost>& costs = _S.getCosts();
size_t itrack = 0;
for ( ; itrack<costs.size() ; ++itrack ) {
ltrace(200) << "Trying itrack:" << itrack << endl;
if ( costs[itrack].isFixed()
or costs[itrack].isBlockage()
or costs[itrack].isInfinite()
or costs[itrack].isOverlapGlobal() )
continue;
bool success = true;
Track* track = _S.getTrack(itrack);
size_t begin = _S.getBegin(itrack);
size_t end = _S.getEnd (itrack);
Net* ownerNet = _segment->getNet();
Interval toFree (_segment->getCanonicalInterval());
for ( size_t i = begin ; success and (i < end) ; i++ ) {
TrackElement* segment2 = track->getSegment(i);
ltrace(200) << "* Looking // " << segment2 << endl;
if ( segment2->getNet() == ownerNet ) continue;
if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue;
if ( segment2->isFixed() ) {
success = false;
continue;
}
DataNegociate* data2 = segment2->getDataNegociate();
if ( not data2 ) {
ltrace(200) << "No DataNegociate, ignoring." << endl;
success = false;
continue;
}
ltrace(200) << "- Forced ripup " << segment2 << endl;
if ( not (success=Manipulator(segment2,_S).ripup(toFree,SegmentAction::OtherRipup)) ) {
continue;
}
}
if ( success ) {
_S.setState ( State::OtherRipup );
_S.addAction ( _segment, SegmentAction::SelfInsert );
_segment->setAxis ( _S.getCost(itrack).getTrack()->getAxis() );
break;
}
}
ltraceout(200);
return (itrack < costs.size());
}
bool Manipulator::desalignate ()
{
ltrace(200) << "Manipulator::desalignate() " << _segment << endl;
@ -2954,14 +3103,14 @@ namespace {
kflags |= (flags & AllowLocalMoveUp ) ? Katabatic::AutoSegment::AllowLocal : 0;
kflags |= (flags & AllowTerminalMoveUp) ? Katabatic::AutoSegment::AllowTerminal : 0;
if ( _segment->isFixed () ) return false;
if ( _segment->isFixed() ) return false;
if ( not (flags & AllowLocalMoveUp) ) {
if ( _segment->isLocal() ) {
if ( not _segment->canPivotUp(0.5) ) return false;
} else {
if ( _segment->getLength() < DbU::lambda(100.0) ) {
if ( not (flags & AllowShortPivotUp) ) return false;
if ( not _segment->canPivotUp(0.5) ) return false;
if ( not _segment->canPivotUp(1.0) ) return false;
}
if ( not _segment->canMoveUp(0.5,kflags) ) return false; // MARK 1
}
@ -3096,7 +3245,7 @@ namespace {
ltrace(200) << "Manipulator::minimize() " << _segment << endl;
if ( _segment->isFixed() ) return false;
if ( !_event->canMinimize() ) return false;
if ( not _event->canMinimize() ) return false;
DbU::Unit minSpan = DbU::Max;
DbU::Unit maxSpan = DbU::Min;
@ -3127,12 +3276,12 @@ namespace {
const vector<TrackElement*>& perpandiculars = _event->getPerpandiculars();
for ( size_t i=0 ; i<perpandiculars.size() ; i++ ) {
DataNegociate* data2 = perpandiculars[i]->getDataNegociate();
if ( !data2 ) continue;
if ( not data2 ) continue;
ltrace(200) << " | " << perpandiculars[i] << endl;
RoutingEvent* event2 = data2->getRoutingEvent();
if ( !event2 ) continue;
if ( not event2 ) continue;
ltrace(200) << " | Constraints: " << event2->getConstraints() << endl;
@ -3144,7 +3293,9 @@ namespace {
ltrace(200) << "punctualSpan: " << punctualSpan
<< " min/max span: [" << DbU::getValueString(minSpan)
<< ":" << DbU::getValueString(minSpan) << "]" << endl;
<< ":" << DbU::getValueString(maxSpan) << "]"
<< " long: [" << minSpan
<< ":" << maxSpan << "]" << endl;
vector<Interval> holes;
for ( size_t itrack=0 ; itrack<_S.getCosts().size() ; itrack++ ) {
@ -3191,24 +3342,27 @@ namespace {
biggestHole = holes[i];
}
if ( !punctualSpan.isEmpty() ) {
DbU::Unit axisHint = 0;
if ( not punctualSpan.isEmpty() ) {
bool success = false;
if ( biggestHole.intersect(punctualSpan) ) {
ltrace(200) << "Go as punctual into biggest hole: " << biggestHole << endl;
axisHint = biggestHole.intersection(punctualSpan).getCenter();
success = true;
} else {
for ( size_t i=0 ; i<holes.size() ; i++ ) {
ltrace(200) << "Trying secondary hole: " << holes[i] << endl;
if ( holes[i].intersect(punctualSpan) ) {
biggestHole = holes[i];
axisHint = biggestHole.intersection(punctualSpan).getCenter();
ltrace(200) << "Go as punctual into secondary hole: " << biggestHole << endl;
success = true;
}
}
}
if ( !success ) {
if ( not success ) {
ltrace(200) << "No suitable hole found." << endl;
return false;
}
@ -3221,10 +3375,10 @@ namespace {
return false;
} else {
ltrace(200) << "Go into biggest hole: " << biggestHole << endl;
axisHint = biggestHole.getCenter();
}
}
DbU::Unit axisHint = biggestHole.intersection(punctualSpan).getCenter();
ltrace(200) << "Axis Hint: " << DbU::getValueString(axisHint) << endl;
for ( size_t i=0 ; i<perpandiculars.size() ; i++ ) {
@ -3304,6 +3458,27 @@ namespace {
}
void Manipulator::repackPerpandiculars ()
{
ltrace(200) << "Manipulator::repackPerpandiculars()" << endl;
const vector<TrackElement*>& perpandiculars = _event->getPerpandiculars();
for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) {
TrackElement* perpandicular = perpandiculars[iperpand];
DataNegociate* data = perpandicular->getDataNegociate();
if ( perpandicular->isFixed () ) continue;
if ( perpandicular->isGlobal() ) continue;
if ( not data ) continue;
if ( RoutingEvent::getStage() == RoutingEvent::Repair )
data->setState ( DataNegociate::Repair );
_S.addAction ( perpandicular, SegmentAction::SelfRipupPerpand );
}
_S.addAction ( _segment, SegmentAction::SelfRipup|SegmentAction::EventLevel4 );
}
// -------------------------------------------------------------------
// Local Functions.
@ -3442,14 +3617,17 @@ namespace Kite {
// Class : "RoutingEvent".
unsigned int RoutingEvent::_stage = RoutingEvent::Negociate;
size_t RoutingEvent::_allocateds = 0;
size_t RoutingEvent::_processeds = 0;
size_t RoutingEvent::_cloneds = 0;
unsigned int RoutingEvent::getStage () { return _stage; }
size_t RoutingEvent::getAllocateds () { return _allocateds; }
size_t RoutingEvent::getProcesseds () { return _processeds; }
size_t RoutingEvent::getCloneds () { return _cloneds; }
void RoutingEvent::setStage ( unsigned int stage ) { _stage = stage; }
void RoutingEvent::resetProcesseds () { _processeds = 0; }
@ -3555,6 +3733,16 @@ namespace Kite {
{ return getState() == DataNegociate::Unimplemented; }
void RoutingEvent::setMode ( unsigned int mode )
{
_mode = mode;
// if ( _mode == Repair ) {
// DataNegociate* data = _segment->getDataNegociate();
// if ( data ) data->setState ( DataNegociate::Repair, true );
// }
}
unsigned int RoutingEvent::getState () const
{
DataNegociate* data = _segment->getDataNegociate();
@ -3586,6 +3774,8 @@ namespace Kite {
void RoutingEvent::cacheAxisHint ()
{
if ( getStage() == Repair ) return;
TrackElement* parent = _segment->getParent();
if ( not parent ) return;
@ -3616,7 +3806,7 @@ namespace Kite {
RoutingEvent* fork = NULL;
if ( isUnimplemented() ) {
if ( (getStage() != Repair) and isUnimplemented() ) {
ltrace(200) << "Reschedule: cancelled (Unimplemented) "
<< (void*)this << " -> " << (void*)fork << ":" << fork << endl;
return NULL;
@ -3636,8 +3826,15 @@ namespace Kite {
ltrace(200) << "Reschedule/Fork: "
<< (void*)this << " -> " << (void*)fork << ":" << fork << endl;
}
if ( fork->_eventLevel < eventLevel )
fork->_eventLevel = eventLevel;
if ( getStage() == Repair ) {
fork->setMode ( RoutingEvent::Repair );
_segment->getDataNegociate()->setState ( DataNegociate::Repair );
}
queue.repush ( fork );
return fork;
@ -3669,11 +3866,11 @@ namespace Kite {
//ltracelevel ( 200 );
//Cfg::getParamInt("misc.traceLevel")->setInt ( 200, Cfg::Parameter::CommandLine );
const vector<RoutingEventLoop::Element>& elements = loop.getElements();
for ( size_t i=0 ; i<elements.size() ; ++i ) {
cerr << " " << setw(2) << elements[i]._count << "| id:" << elements[i]._id << "\n";
}
cerr << endl;
//const vector<RoutingEventLoop::Element>& elements = loop.getElements();
//for ( size_t i=0 ; i<elements.size() ; ++i ) {
// cerr << " " << setw(2) << elements[i]._count << "| id:" << elements[i]._id << "\n";
//}
//cerr << endl;
}
#if LOOP_DEBUG
@ -3702,16 +3899,13 @@ namespace Kite {
setState ( DataNegociate::Unimplemented );
ostringstream message;
message << "Kite has detected a loop between the following Segments:\n<tt>";
message << "[BUG] Kite has detected a loop between the following Segments:";
const vector<RoutingEventLoop::Element>& elements = loop.getElements();
for ( size_t i=0 ; i<elements.size() ; ++i ) {
message << setw(2) << elements[i]._count << "| id:"
<< elements[i]._id << "\n";
message << "\n" << setw(10) << elements[i]._count << "| id:" << elements[i]._id;
}
message << "</tt>";
cerr << message << endl;
cerr << message.str() << endl;
#endif
}
@ -3742,17 +3936,17 @@ namespace Kite {
_preCheck(_segment);
_eventLevel = 0;
if ( _mode < PostPack ) history.push ( this );
history.push ( this );
if ( isProcessed() || isDisabled() ) {
if ( isProcessed() or isDisabled() ) {
ltrace(200) << "Already processed or disabled." << endl;
} else {
setProcessed ();
switch ( _mode ) {
case Negociate: _processNegociate ( queue, history ); break;
case Pack:
case PostPack: _processPacking ( queue, history ); break;
case Pack: _processPack ( queue, history ); break;
case Repair: _processRepair ( queue, history ); break;
default:
cerr << Bug("RoutingEvent::process() - Unknown mode value:%d.",_mode) << endl;
break;
@ -3818,15 +4012,15 @@ namespace Kite {
_axisHistory = _segment->getAxis();
_eventLevel = 0;
Session::addInsertEvent ( _segment, S.getCost(itrack).getTrack() );
Manipulator(_segment,S).reprocessPerpandiculars ();
//Manipulator(_segment,S).reprocessPerpandiculars ();
S.setState ( State::SelfInserted );
if ( _segment->isLocal()
and _segment->isTerminal()
and ( S.getData()->getState() >= DataNegociate::MoveUp ) ) {
ltrace(200) << "Last chance: fixing " << _segment << endl;
_segment->base()->setFixed ( true );
}
// if ( _segment->isLocal()
// and _segment->isTerminal()
// and ( S.getData()->getState() >= DataNegociate::MoveUp ) ) {
// ltrace(200) << "Last chance: fixing " << _segment << endl;
// _segment->base()->setFixed ( true );
// }
} else {
// Do ripup.
if ( S.getState() == State::EmptyTrackList ) {
@ -3867,9 +4061,9 @@ namespace Kite {
}
void RoutingEvent::_processPacking ( RoutingEventQueue& queue, RoutingEventHistory& history )
void RoutingEvent::_processPack ( RoutingEventQueue& queue, RoutingEventHistory& history )
{
ltrace(200) << "* Mode:Packing." << endl;
ltrace(200) << "* Mode:Pack." << endl;
if ( _segment->getTrack() != NULL ) {
ltrace(200) << "* Cancel: already in Track." << endl;
@ -3894,13 +4088,63 @@ namespace Kite {
Session::addInsertEvent ( _segment, S.getCost(0).getTrack() );
S.setState ( State::SelfInserted );
} else {
ltrace(200) << "Packing failed." << endl;
if ( _mode == Pack ) {
ltrace(200) << "Pack failed." << endl;
_mode = Negociate;
S.addAction ( _segment, SegmentAction::SelfInsert );
S.doActions ();
}
}
void RoutingEvent::_processRepair ( RoutingEventQueue& queue, RoutingEventHistory& history )
{
ltrace(200) << "* Mode:Repair." << endl;
if ( _segment->getTrack() != NULL ) {
ltrace(200) << "* Cancel: already in Track." << endl;
return;
}
// if ( !_canHandleConstraints ) {
// ltrace(200) << "* Cancel: cannot handle constraints." << endl;
// return;
// }
State S ( this, queue, history );
if ( S.getState() == State::MissingData ) return;
if ( S.getState() == State::EmptyTrackList ) return;
ltracein(200);
for ( size_t i = 0 ; i < S.getCosts().size() ; i++ )
ltrace(200) << "| " << S.getCost(i) << endl;
ltraceout(200);
if ( S.getCosts().size() and S.getCost(0).isFree() ) {
ltrace(200) << "Insert in free space." << endl;
Session::addInsertEvent ( _segment, S.getCost(0).getTrack() );
S.setState ( State::SelfInserted );
} else {
switch ( S.getData()->getStateCount() ) {
case 1:
// First try: minimize.
//S.getData()->setState ( DataNegociate::Repair );
Manipulator(_segment,S).minimize ();
S.addAction ( _segment, SegmentAction::SelfInsert );
S.doActions ();
queue.commit ();
break;
case 2:
// Second try: failed re-inserted first.
//S.getData()->setState ( DataNegociate::Repair );
Manipulator(_segment,S).repackPerpandiculars ();
S.addAction ( _segment, SegmentAction::SelfInsert );
S.doActions ();
queue.commit ();
break;
default:
ltrace(200) << "Repair failed." << endl;
break;
}
}
}
@ -3921,12 +4165,24 @@ namespace Kite {
_segment->base()->getConstraints ( _constraints );
_segment->base()->getOptimal ( _optimal );
ltrace(200) << "Stage:" << RoutingEvent::getStage() << endl;
if ( RoutingEvent::getStage() == RoutingEvent::Repair ) {
ltrace(200) << "Expanding:" << _constraints << endl;
// Ugly: direct uses of Cell Gauge.
_constraints.inflate ( DbU::lambda(50.0) );
ltrace(200) << "Expanding (after):" << _constraints << endl;
}
// else if ( _segment->isDogleg()
// and (_segment->getDataNegociate()->getState() >= DataNegociate::MaximumSlack) ) {
// _constraints.inflate ( DbU::lambda(25.0) );
// }
ltrace(200) << "| Raw Track Constraint: " << _constraints << endl;
_validConstraints = true;
}
if ( !_validPerpandiculars ) {
if ( not _validPerpandiculars ) {
TrackElement* perpandicular;
Interval canonical;
@ -3969,12 +4225,12 @@ namespace Kite {
_tracksNb = 0;
ltrace(200) << "| Perpandicular Free: " << _perpandicular << endl;
if ( !_perpandicular.isEmpty() ) {
if ( not _perpandicular.isEmpty() ) {
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer());
Track* track = plane->getTrackByPosition(_perpandicular.getVMin());
if ( track && (track->getAxis() < _perpandicular.getVMin()) ) track = track->getNext();
for ( ; track && (track->getAxis() <= _perpandicular.getVMax())
if ( track and (track->getAxis() < _perpandicular.getVMin()) ) track = track->getNext();
for ( ; track and (track->getAxis() <= _perpandicular.getVMax())
; track = track->getNext(), _tracksNb++ );
}
if ( not _tracksNb ) {

View File

@ -285,9 +285,13 @@ namespace Kite {
}
TrackCost Track::getOverlapCost ( Interval interval, Net* net, size_t begin, size_t end ) const
TrackCost Track::getOverlapCost ( Interval interval
, Net* net
, size_t begin
, size_t end
, unsigned int flags ) const
{
TrackCost cost ( const_cast<Track*>(this), interval, begin, end, net );
TrackCost cost ( const_cast<Track*>(this), interval, begin, end, net, flags );
ltrace(190) << "getOverlapCost() @" << DbU::getValueString(_axis)
<< " [" << DbU::getValueString(interval.getVMin())
@ -317,12 +321,15 @@ namespace Kite {
}
for ( ; begin < end ; begin++ ) {
Interval overlap = interval.getIntersection ( _segments[begin]->getCanonicalInterval() );
//if ( not overlap.isEmpty() ) {
if ( _segments[begin]->getNet() == net ) {
cost.incDeltaShared ( _segments[begin]->getCanonicalInterval().intersection(interval).getSize() );
cost.incDeltaShared ( overlap.getSize() );
}
ltrace(190) << "| overlap: " << _segments[begin] << endl;
_segments[begin]->incOverlapCost ( net, cost );
if ( cost.isInfinite() ) break;
//}
}
ltraceout(148);
@ -331,20 +338,20 @@ namespace Kite {
}
TrackCost Track::getOverlapCost ( Interval interval, Net* net ) const
TrackCost Track::getOverlapCost ( Interval interval, Net* net, unsigned int flags ) const
{
size_t begin;
size_t end;
getOverlapBounds ( interval, begin, end );
return getOverlapCost ( interval, net, begin, end );
return getOverlapCost ( interval, net, begin, end, flags );
}
TrackCost Track::getOverlapCost ( TrackElement* segment ) const
TrackCost Track::getOverlapCost ( TrackElement* segment, unsigned int flags ) const
{
return getOverlapCost ( segment->getCanonicalInterval(), segment->getNet() );
return getOverlapCost ( segment->getCanonicalInterval(), segment->getNet(), flags );
}

View File

@ -52,8 +52,10 @@ namespace Kite {
, size_t begin
, size_t end
, Net* net
, unsigned int flags
)
: _track (track)
: _flags (flags)
, _track (track)
, _begin (begin)
, _end (end)
, _interval (interval)
@ -65,12 +67,14 @@ namespace Kite {
, _leftOverlap (false)
, _rightOverlap (false)
, _overlapGlobal (false)
, _globalEnclosed (false)
, _terminals (0)
, _delta (-interval.getSize())
, _deltaShared (0)
, _deltaPerpand (0)
, _axisWeight (0)
, _distanceToFixed(DbU::lambda(100.0))
, _longuestOverlap(0)
, _dataState (0)
, _ripupCount (0)
{
@ -131,13 +135,21 @@ namespace Kite {
//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 ( not (_flags & TrackCost::IgnoreAxisWeight) ) {
if ( lhs._axisWeight < rhs._axisWeight ) return true;
@ -162,7 +174,7 @@ namespace Kite {
void TrackCost::consolidate ()
{
if ( !_infinite && !_hardOverlap ) {
if ( not _infinite and not _hardOverlap ) {
//_deltaPerpand += - (_deltaShared << 1);
_delta += - _deltaShared;
}
@ -180,12 +192,14 @@ namespace Kite {
s += " " + string ( (_blockage )?"b":"-" );
s += string ( (_hardOverlap )?"h":"-" );
s += string ( (_overlap )?"o":"-" );
s += string ( (_overlapGlobal)?"g":"-" );
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 += ">";

View File

@ -138,6 +138,7 @@ namespace Kite {
// Former inline functions.
AutoSegment* TrackElement::base () const { return NULL; }
bool TrackElement::isBipoint () const { return false; }
bool TrackElement::isCreated () const { return false; }
bool TrackElement::isFixed () const { return false; }
bool TrackElement::isBlockage () const { return false; }
@ -147,6 +148,7 @@ namespace Kite {
bool TrackElement::isGlobal () const { return not isLocal(); }
bool TrackElement::isLocked () const { return false; }
bool TrackElement::isTerminal () const { return false; }
bool TrackElement::isDogleg () const { return false; }
bool TrackElement::isRevalidated () const { return false; }
bool TrackElement::isRouted () const { return true; }
bool TrackElement::isSlackened () const { return false; }
@ -179,6 +181,7 @@ namespace Kite {
bool TrackElement::canPivotUp ( float ) const { return false; };
bool TrackElement::canPivotDown ( float ) const { return false; };
bool TrackElement::canMoveUp ( float, unsigned int ) const { return false; };
float TrackElement::getMaxUnderDensity ( unsigned int ) const { return 0.0; };
bool TrackElement::canDogLeg () { return false; };
bool TrackElement::canDogLeg ( Interval ) { return false; };
bool TrackElement::canDogLegAt ( Katabatic::GCell*, unsigned int ) { return false; };

View File

@ -133,6 +133,7 @@ namespace Kite {
// Formerly Inline Functions.
AutoSegment* TrackSegment::base () const { return _base; }
bool TrackSegment::isBipoint () const { return _base->isBipoint(); }
bool TrackSegment::isCreated () const { return _created; }
bool TrackSegment::isFixed () const { return _base->isFixed(); }
bool TrackSegment::isStrap () const { return _base->isCanonicalStrap(); }
@ -141,6 +142,7 @@ namespace Kite {
bool TrackSegment::isGlobal () const { return !isLocal(); }
bool TrackSegment::isLocked () const { return _lock; }
bool TrackSegment::isTerminal () const { return _base->isTerminal(); }
bool TrackSegment::isDogleg () const { return _base->isDogleg(); }
bool TrackSegment::isRevalidated () const { return _revalidated; }
bool TrackSegment::isRouted () const { return _routed; }
bool TrackSegment::isSlackened () const { return _base->isSlackened(); }
@ -464,6 +466,10 @@ namespace Kite {
}
float TrackSegment::getMaxUnderDensity ( unsigned int flags ) const
{ return _base->getMaxUnderDensity ( flags ); }
bool TrackSegment::canPivotUp ( float reserve ) const
{ return _base->canPivotUp(reserve); }

View File

@ -74,6 +74,7 @@ namespace Kite {
, MoveUp = 9
, MaximumSlack =10
, Unimplemented =11
, Repair =12
};
public:

View File

@ -90,13 +90,15 @@ namespace Kite {
friend class Compare;
public:
enum Mode { Negociate=1, Pack=2, PostPack=3 };
enum Mode { Negociate=1, Pack=2, Repair=3 };
public:
static unsigned int getStage ();
static size_t getAllocateds ();
static size_t getProcesseds ();
static size_t getCloneds ();
static void resetProcesseds ();
static void setStage ( unsigned int );
public:
static RoutingEvent* create ( TrackElement*, unsigned int mode=Negociate );
RoutingEvent* clone () const;
@ -137,7 +139,7 @@ namespace Kite {
);
void setSegment ( TrackElement* );
RoutingEvent* reschedule ( RoutingEventQueue&, unsigned int eventLevel );
inline void setMode ( unsigned int );
void setMode ( unsigned int );
void setState ( unsigned int );
inline void setProcessed ( bool state=true );
inline void setDisabled ( bool state=true );
@ -152,7 +154,8 @@ namespace Kite {
inline void incInsertState ();
inline void resetInsertState ();
void _processNegociate ( RoutingEventQueue&, RoutingEventHistory& );
void _processPacking ( RoutingEventQueue&, RoutingEventHistory& );
void _processPack ( RoutingEventQueue&, RoutingEventHistory& );
void _processRepair ( RoutingEventQueue&, RoutingEventHistory& );
Record* _getRecord () const;
string _getString () const;
string _getTypeName () const;
@ -162,6 +165,7 @@ namespace Kite {
protected:
// Attributes.
static unsigned int _stage;
static size_t _allocateds;
static size_t _processeds;
static size_t _cloneds;
@ -221,7 +225,6 @@ namespace Kite {
inline unsigned int RoutingEvent::getTracksFree () const { return _tracksFree; }
inline unsigned int RoutingEvent::getInsertState () const { return _insertState; }
inline Katabatic::GCell* RoutingEvent::getShearGCell () const { return _shearGCell; }
inline void RoutingEvent::setMode ( unsigned int mode ) { _mode = mode; }
inline void RoutingEvent::setProcessed ( bool state ) { _processed = state; }
inline void RoutingEvent::setDisabled ( bool state ) { _disabled = state; }
inline void RoutingEvent::setMinimized ( bool state ) { _minimized = state; }

View File

@ -2,13 +2,13 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved
//
// ===================================================================
//
// $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 |
@ -20,7 +20,7 @@
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
#ifndef __KITE_ROUTING_EVENT_QUEUE__

View File

@ -105,9 +105,9 @@ namespace Kite {
TrackElement* getSegment ( DbU::Unit position ) const;
void getIBounds ( DbU::Unit position, size_t& begin, size_t& end, unsigned int& state ) const;
void getOverlapBounds ( Interval, size_t& begin, size_t& end ) const;
TrackCost getOverlapCost ( Interval, Net*, size_t begin, size_t end ) const;
TrackCost getOverlapCost ( Interval, Net* ) const;
TrackCost getOverlapCost ( TrackElement* ) const;
TrackCost getOverlapCost ( Interval, Net*, size_t begin, size_t end, unsigned int flags ) const;
TrackCost getOverlapCost ( Interval, Net*, unsigned int flags ) const;
TrackCost getOverlapCost ( TrackElement*, unsigned int flags ) const;
void getTerminalWeight ( Interval, Net*, size_t& count, unsigned int& weight ) const;
DbU::Unit getSourcePosition ( size_t index ) const;
DbU::Unit getSourcePosition ( vector<TrackElement*>::iterator ) const;

View File

@ -2,13 +2,13 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved
//
// ===================================================================
//
// $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 |
@ -20,7 +20,7 @@
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
@ -51,7 +51,11 @@ namespace Kite {
class TrackCost {
public:
enum Flags { IgnoreAxisWeight=0x1, DiscardGlobals=0x2 };
enum Flags { IgnoreAxisWeight = 0x1
, DiscardGlobals = 0x2
, IgnoreSharedLength = 0x4
, LocalAndTopDepth = 0x1
};
public:
// Sub-Class: "CompareByDelta()".
@ -73,6 +77,7 @@ namespace Kite {
, size_t begin
, size_t end
, Net* net
, unsigned int flags
);
~TrackCost ();
inline bool isBlockage () const;
@ -83,7 +88,9 @@ namespace Kite {
inline bool isRightOverlap () const;
inline bool isHardOverlap () const;
inline bool isOverlapGlobal () const;
inline bool isGlobalEnclosed () const;
bool isFree () const;
inline unsigned int getFlags () const;
inline Track* getTrack () const;
inline size_t getBegin () const;
inline size_t getEnd () const;
@ -91,6 +98,7 @@ namespace Kite {
inline unsigned int getTerminals () const;
inline DbU::Unit getDelta () const;
inline DbU::Unit getDeltaPerpand () const;
inline DbU::Unit getLongestOverlap () const;
inline long getAxisWeight () const;
inline int getRipupCount () const;
inline unsigned int getDataState () const;
@ -102,11 +110,13 @@ namespace Kite {
inline void setRightOverlap ();
inline void setHardOverlap ();
inline void setOverlapGlobal ();
inline void setGlobalEnclosed ();
inline void incTerminals ( unsigned int );
inline void incDelta ( DbU::Unit );
inline void incDeltaPerpand ( DbU::Unit );
inline void incDeltaShared ( DbU::Unit );
inline void setAxisWeight ( DbU::Unit );
inline void setLonguestOverlap ( DbU::Unit );
inline void mergeRipupCount ( int );
inline void mergeDataState ( unsigned int );
void consolidate ();
@ -117,6 +127,7 @@ namespace Kite {
// Attributes.
protected:
unsigned int _flags;
Track* _track;
size_t _begin;
size_t _end;
@ -129,12 +140,14 @@ namespace Kite {
bool _leftOverlap;
bool _rightOverlap;
bool _overlapGlobal;
bool _globalEnclosed;
unsigned int _terminals;
DbU::Unit _delta;
DbU::Unit _deltaShared;
DbU::Unit _deltaPerpand;
DbU::Unit _axisWeight;
DbU::Unit _distanceToFixed;
DbU::Unit _longuestOverlap;
unsigned int _dataState;
int _ripupCount;
@ -150,11 +163,14 @@ namespace Kite {
inline bool TrackCost::isRightOverlap () const { return _rightOverlap; }
inline bool TrackCost::isHardOverlap () const { return _hardOverlap; }
inline bool TrackCost::isOverlapGlobal () const { return _overlapGlobal; }
inline bool TrackCost::isGlobalEnclosed () const { return _globalEnclosed; }
inline unsigned int TrackCost::getFlags () const { return _flags; }
inline Track* TrackCost::getTrack () const { return _track; }
inline size_t TrackCost::getBegin () const { return _begin; }
inline size_t TrackCost::getEnd () const { return _end; }
inline const Interval& TrackCost::getInterval () const { return _interval; }
inline unsigned int TrackCost::getTerminals () const { return _terminals; }
inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; }
inline DbU::Unit TrackCost::getDelta () const { return _delta; }
inline long TrackCost::getAxisWeight () const { return _axisWeight; }
inline int TrackCost::getRipupCount () const { return _ripupCount; }
@ -166,12 +182,14 @@ namespace Kite {
inline void TrackCost::setLeftOverlap () { _leftOverlap = true; }
inline void TrackCost::setRightOverlap () { _rightOverlap = true; }
inline void TrackCost::setHardOverlap () { _hardOverlap = true; }
inline void TrackCost::setOverlapGlobal() { _overlapGlobal = true; }
inline void TrackCost::setOverlapGlobal () { _overlapGlobal = true; }
inline void TrackCost::setGlobalEnclosed () { _globalEnclosed = true; }
inline void TrackCost::incTerminals ( unsigned int terminals ) { _terminals += terminals; }
inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; }
inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; }
inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; }
inline void TrackCost::setAxisWeight ( DbU::Unit weight ) { _axisWeight = weight; }
inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = (overlap > _longuestOverlap) ? overlap : _longuestOverlap; }
inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = (count>_ripupCount)?count:_ripupCount; }
inline void TrackCost::mergeDataState ( unsigned int state ) { _dataState = (state>_dataState)?state:_dataState; }
inline string TrackCost::_getTypeName () const { return "TrackCost"; }

View File

@ -112,12 +112,14 @@ namespace Kite {
virtual bool isGlobal () const;
virtual bool isLocked () const;
virtual bool isTerminal () const;
virtual bool isDogleg () const;
virtual bool isRevalidated () const;
virtual bool isRouted () const;
virtual bool isSlackened () const;
virtual bool isSlackenDogLeg () const;
virtual bool isHorizontal () const = 0;
virtual bool isVertical () const = 0;
virtual bool isBipoint () const;
virtual bool allowOutsideGCell () const;
virtual bool canDesalignate () const;
virtual bool canGoOutsideGCell () const;
@ -125,6 +127,7 @@ namespace Kite {
virtual bool canPivotUp ( float reserve ) const;
virtual bool canPivotDown ( float reserve ) const;
virtual bool canMoveUp ( float reserve, unsigned int flags=AutoSegment::Propagate|AutoSegment::PerpandicularFrag ) const;
virtual float getMaxUnderDensity ( unsigned int flags=AutoSegment::Propagate ) const;
virtual bool canRipple () const;
virtual bool hasSourceDogLeg () const;
virtual bool hasTargetDogLeg () const;

View File

@ -59,6 +59,7 @@ namespace Kite {
static TrackElement* create ( AutoSegment*, Track*, bool& created );
public:
virtual AutoSegment* base () const;
virtual bool isBipoint () const;
virtual bool isCreated () const;
virtual bool isFixed () const;
virtual bool isStrap () const;
@ -67,6 +68,7 @@ namespace Kite {
virtual bool isGlobal () const;
virtual bool isLocked () const;
virtual bool isTerminal () const;
virtual bool isDogleg () const;
virtual bool isRevalidated () const;
virtual bool isSlackened () const;
virtual bool isSlackenDogLeg () const;
@ -80,6 +82,7 @@ namespace Kite {
virtual bool canPivotUp ( float reserve ) const;
virtual bool canPivotDown ( float reserve ) const;
virtual bool canMoveUp ( float reserve, unsigned int flags ) const;
virtual float getMaxUnderDensity ( unsigned int flags ) const;
virtual bool canRipple () const;
virtual bool hasSourceDogLeg () const;
virtual bool hasTargetDogLeg () const;