diff --git a/kite/src/DataNegociate.cpp b/kite/src/DataNegociate.cpp index b6e87740..d8a89540 100644 --- a/kite/src/DataNegociate.cpp +++ b/kite/src/DataNegociate.cpp @@ -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; } diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index 7125e6fd..bae024eb 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -268,7 +268,8 @@ namespace Kite { forEach ( Knik::Vertex*, ivertex, _knik->getRoutingGraph()->getVertexes() ) { for ( int i=0 ; i<2 ; ++i ) { - Knik::Edge* edge = NULL; + 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; } diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index d596bb9e..f1f8f6a1 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -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,7 +125,9 @@ namespace { cost.setOverlap (); if ( segment->isLocal() or (Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) < 3) ) cost.incTerminals ( data->getCost().getTerminals()*100 ); - cost.incDelta ( intersect.getSize() ); + + 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,21 +395,25 @@ 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 (); if (tty::enabled()) { - cmess2 << " " << tty::cr; cmess2.flush (); } else { - cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " << event->getSegment() @@ -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 (tty::enabled()) { - cmess1 << " " << tty::cr; - cmess1.flush (); - } else { - cmess1 << " " << endl; - } + 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()) { + cmess2 << " " << tty::cr; + cmess2.flush (); + } else { + cmess2 << " 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 << " " << tty::cr; + // cmess1.flush (); + // } else { + // cmess1 << " " << 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 (); diff --git a/kite/src/RoutingEvent.cpp b/kite/src/RoutingEvent.cpp index 45e54f6d..45556f80 100644 --- a/kite/src/RoutingEvent.cpp +++ b/kite/src/RoutingEvent.cpp @@ -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 @@ -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()) ); @@ -1071,8 +1084,8 @@ namespace { if ( _costs.empty() ) { Track* nearest = plane->getTrackByPosition(_constraint.getCenter()); - if ( (nearest->getAxis() < _constraint.getVMin()) - || (nearest->getAxis() > _constraint.getVMax()) ) { + if ( (nearest->getAxis() < _constraint.getVMin()) + 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 ( ; itrackgetNet(); + 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; + // } + + vector gcells; + segment->getGCells ( gcells ); + + AutoSegment::DepthLengthSet globals; + for ( size_t i=0 ; i* 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; + + globals.insert ( (*gcellGlobals)[i] ); + } } - GCell* gcell = segment->base()->getAutoSource()->getGCell(); - const vector* globals = (segment->isHorizontal()) - ? gcell->getHSegments() : gcell->getVSegments(); + AutoSegment::DepthLengthSet::iterator iglobal = globals.begin(); + for ( ; iglobal != globals.end() ; ++iglobal ) { + TrackElement* gsegment = Session::lookup ( *iglobal ); + ltrace(200) << "| " << gsegment << endl; - 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()); - if ( gdepth != depth ) continue; - - ltrace(200) << "| " << (*globals)[i] << endl; - - TrackElement* gsegment = Session::lookup ( (*globals)[i] ); - ltrace(200) << "|*" << (*globals)[i] << 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; - } + if ( Manipulator(gsegment,*this).moveUp() ) { + 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& costs = _S.getCosts(); + size_t itrack = 0; + for ( ; itrackgetNet(); + 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& perpandiculars = _event->getPerpandiculars(); for ( size_t i=0 ; igetDataNegociate(); - 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,9 +3293,11 @@ namespace { ltrace(200) << "punctualSpan: " << punctualSpan << " min/max span: [" << DbU::getValueString(minSpan) - << ":" << DbU::getValueString(minSpan) << "]" << endl; + << ":" << DbU::getValueString(maxSpan) << "]" + << " long: [" << minSpan + << ":" << maxSpan << "]" << endl; - vector holes; + vector holes; for ( size_t itrack=0 ; itrack<_S.getCosts().size() ; itrack++ ) { size_t begin = _S.getBegin(itrack); size_t end = _S.getEnd (itrack); @@ -3156,7 +3307,7 @@ namespace { ltrace(200) << "Looking for holes in " << _S.getCost(itrack) << endl; - TrackElement* otherPrevious = NULL; + TrackElement* otherPrevious = NULL; // ToDo: Manage disjoint but subsequent segment of a Net. // (currently, that hole will not be found). for ( ; begin < end ; begin++ ) { @@ -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& perpandiculars = _event->getPerpandiculars(); + for ( size_t iperpand=0 ; iperpandgetDataNegociate(); + + 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 ); + } // ------------------------------------------------------------------- @@ -3442,15 +3617,18 @@ namespace Kite { // Class : "RoutingEvent". - size_t RoutingEvent::_allocateds = 0; - size_t RoutingEvent::_processeds = 0; - size_t RoutingEvent::_cloneds = 0; + unsigned int RoutingEvent::_stage = RoutingEvent::Negociate; + size_t RoutingEvent::_allocateds = 0; + size_t RoutingEvent::_processeds = 0; + size_t RoutingEvent::_cloneds = 0; - size_t RoutingEvent::getAllocateds () { return _allocateds; } - size_t RoutingEvent::getProcesseds () { return _processeds; } - size_t RoutingEvent::getCloneds () { return _cloneds; } - void RoutingEvent::resetProcesseds () { _processeds = 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; } RoutingEvent::RoutingEvent ( TrackElement* segment, unsigned int mode ) @@ -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& elements = loop.getElements(); - for ( size_t i=0 ; i& elements = loop.getElements(); + //for ( size_t i=0 ; i"; + message << "[BUG] Kite has detected a loop between the following Segments:"; const vector& elements = loop.getElements(); for ( size_t i=0 ; i"; - - 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,11 +4088,61 @@ namespace Kite { Session::addInsertEvent ( _segment, S.getCost(0).getTrack() ); S.setState ( State::SelfInserted ); } else { - ltrace(200) << "Packing failed." << endl; - if ( _mode == Pack ) { - _mode = Negociate; - S.addAction ( _segment, SegmentAction::SelfInsert ); - S.doActions (); + 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 ) { diff --git a/kite/src/Track.cpp b/kite/src/Track.cpp index ccf1e218..0e64b1f3 100644 --- a/kite/src/Track.cpp +++ b/kite/src/Track.cpp @@ -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(this), interval, begin, end, net ); + TrackCost cost ( const_cast(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++ ) { - if ( _segments[begin]->getNet() == net ) { - cost.incDeltaShared ( _segments[begin]->getCanonicalInterval().intersection(interval).getSize() ); - } - ltrace(190) << "| overlap: " << _segments[begin] << endl; - _segments[begin]->incOverlapCost ( net, cost ); - if ( cost.isInfinite() ) break; + Interval overlap = interval.getIntersection ( _segments[begin]->getCanonicalInterval() ); + //if ( not overlap.isEmpty() ) { + if ( _segments[begin]->getNet() == net ) { + 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 ); } diff --git a/kite/src/TrackCost.cpp b/kite/src/TrackCost.cpp index 4f8ead82..8b116903 100644 --- a/kite/src/TrackCost.cpp +++ b/kite/src/TrackCost.cpp @@ -47,13 +47,15 @@ namespace Kite { // Class : "TrackCost". - TrackCost::TrackCost ( Track* track - , const Interval& interval - , size_t begin - , size_t end - , Net* net + TrackCost::TrackCost ( Track* track + , const Interval& interval + , 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 ( lhs._delta < rhs._delta ) return true; - if ( lhs._delta > rhs._delta ) 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; } @@ -177,15 +189,17 @@ namespace Kite { s += " " + getString(_dataState); s += "+" + getString(_ripupCount); s += ":" + getString((_dataState<<2)+_ripupCount); - s += " " + string ( (_blockage )?"b":"-" ); - s += string ( (_hardOverlap )?"h":"-" ); - s += string ( (_overlap )?"o":"-" ); - s += string ( (_overlapGlobal)?"g":"-" ); + s += " " + string ( (_blockage )?"b":"-" ); + s += string ( (_hardOverlap )?"h":"-" ); + s += string ( (_overlap )?"o":"-" ); + 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 += ">"; diff --git a/kite/src/TrackElement.cpp b/kite/src/TrackElement.cpp index 6bb60e21..8aa4ecd1 100644 --- a/kite/src/TrackElement.cpp +++ b/kite/src/TrackElement.cpp @@ -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; }; diff --git a/kite/src/TrackSegment.cpp b/kite/src/TrackSegment.cpp index fe6b238f..2e89d4aa 100644 --- a/kite/src/TrackSegment.cpp +++ b/kite/src/TrackSegment.cpp @@ -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); } diff --git a/kite/src/kite/DataNegociate.h b/kite/src/kite/DataNegociate.h index 8305960a..a34921df 100644 --- a/kite/src/kite/DataNegociate.h +++ b/kite/src/kite/DataNegociate.h @@ -74,6 +74,7 @@ namespace Kite { , MoveUp = 9 , MaximumSlack =10 , Unimplemented =11 + , Repair =12 }; public: diff --git a/kite/src/kite/RoutingEvent.h b/kite/src/kite/RoutingEvent.h index 11f55456..1f8f9b00 100644 --- a/kite/src/kite/RoutingEvent.h +++ b/kite/src/kite/RoutingEvent.h @@ -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; } diff --git a/kite/src/kite/RoutingEventQueue.h b/kite/src/kite/RoutingEventQueue.h index 3584b49b..945b42c7 100644 --- a/kite/src/kite/RoutingEventQueue.h +++ b/kite/src/kite/RoutingEventQueue.h @@ -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__ diff --git a/kite/src/kite/Track.h b/kite/src/kite/Track.h index 06253d94..009b5728 100644 --- a/kite/src/kite/Track.h +++ b/kite/src/kite/Track.h @@ -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::iterator ) const; diff --git a/kite/src/kite/TrackCost.h b/kite/src/kite/TrackCost.h index 9a020046..5a6838be 100644 --- a/kite/src/kite/TrackCost.h +++ b/kite/src/kite/TrackCost.h @@ -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()". @@ -68,55 +72,62 @@ namespace Kite { }; public: - TrackCost ( Track* track - , const Interval& interval - , size_t begin - , size_t end - , Net* net - ); - ~TrackCost (); - inline bool isBlockage () const; - inline bool isFixed () const; - inline bool isInfinite () const; - inline bool isOverlap () const; - inline bool isLeftOverlap () const; - inline bool isRightOverlap () const; - inline bool isHardOverlap () const; - inline bool isOverlapGlobal () const; - bool isFree () const; - inline Track* getTrack () const; - inline size_t getBegin () const; - inline size_t getEnd () const; - inline const Interval& getInterval () const; - inline unsigned int getTerminals () const; - inline DbU::Unit getDelta () const; - inline DbU::Unit getDeltaPerpand () const; - inline long getAxisWeight () const; - inline int getRipupCount () const; - inline unsigned int getDataState () const; - inline void setBlockage (); - inline void setFixed (); - inline void setInfinite (); - inline void setOverlap (); - inline void setLeftOverlap (); - inline void setRightOverlap (); - inline void setHardOverlap (); - inline void setOverlapGlobal (); - 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 mergeRipupCount ( int ); - inline void mergeDataState ( unsigned int ); - void consolidate (); - Record* _getRecord () const; - string _getString () const; - inline string _getTypeName () const; + TrackCost ( Track* track + , const Interval& interval + , size_t begin + , size_t end + , Net* net + , unsigned int flags + ); + ~TrackCost (); + inline bool isBlockage () const; + inline bool isFixed () const; + inline bool isInfinite () const; + inline bool isOverlap () const; + inline bool isLeftOverlap () const; + 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; + inline const Interval& getInterval () const; + 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; + inline void setBlockage (); + inline void setFixed (); + inline void setInfinite (); + inline void setOverlap (); + inline void setLeftOverlap (); + 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 (); + Record* _getRecord () const; + string _getString () const; + inline string _getTypeName () const; // Operators. // 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; @@ -142,39 +155,44 @@ namespace Kite { // Inline Functions. - inline bool TrackCost::isBlockage () const { return _blockage; } - inline bool TrackCost::isFixed () const { return _fixed; } - inline bool TrackCost::isInfinite () const { return _infinite; } - inline bool TrackCost::isOverlap () const { return _overlap; } - inline bool TrackCost::isLeftOverlap () const { return _leftOverlap; } - inline bool TrackCost::isRightOverlap () const { return _rightOverlap; } - inline bool TrackCost::isHardOverlap () const { return _hardOverlap; } - inline bool TrackCost::isOverlapGlobal () const { return _overlapGlobal; } - 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::getDelta () const { return _delta; } - inline long TrackCost::getAxisWeight () const { return _axisWeight; } - inline int TrackCost::getRipupCount () const { return _ripupCount; } - inline unsigned int TrackCost::getDataState () const { return _dataState; } - inline void TrackCost::setBlockage () { _blockage = true; } - inline void TrackCost::setFixed () { _fixed = true; } - inline void TrackCost::setInfinite () { _infinite = true; } - inline void TrackCost::setOverlap () { _overlap = true; } - 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::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::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"; } + inline bool TrackCost::isBlockage () const { return _blockage; } + inline bool TrackCost::isFixed () const { return _fixed; } + inline bool TrackCost::isInfinite () const { return _infinite; } + inline bool TrackCost::isOverlap () const { return _overlap; } + inline bool TrackCost::isLeftOverlap () const { return _leftOverlap; } + 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; } + inline unsigned int TrackCost::getDataState () const { return _dataState; } + inline void TrackCost::setBlockage () { _blockage = true; } + inline void TrackCost::setFixed () { _fixed = true; } + inline void TrackCost::setInfinite () { _infinite = true; } + inline void TrackCost::setOverlap () { _overlap = true; } + 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::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"; } inline TrackCost::Compare::Compare ( unsigned int flags ) : _flags(flags) { } diff --git a/kite/src/kite/TrackElement.h b/kite/src/kite/TrackElement.h index 0a1659f8..f566d9ff 100644 --- a/kite/src/kite/TrackElement.h +++ b/kite/src/kite/TrackElement.h @@ -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; diff --git a/kite/src/kite/TrackSegment.h b/kite/src/kite/TrackSegment.h index f422fa8d..ae042b33 100644 --- a/kite/src/kite/TrackSegment.h +++ b/kite/src/kite/TrackSegment.h @@ -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;