From 3c9d064fd8b4aaebb45c613f49c0f78f6bde3d8b Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 30 Dec 2010 18:42:17 +0000 Subject: [PATCH] * ./Kite: - New: In BuildPowerRails, special processing for the power ring segments. The "diagonal" of vias at each corner is causing a misbehavior of the routing algorithm (due to fully saturated GCells in one direction). As a temporary fix, extend the segments so they form a "square corner". (problem arise on "d_in_i(22)"). - New: In RoutingEvent::_processNegociate, disable the "isForcedToHint()" feature. No noticeable loss of quality or speed. - New: In TrackElement/TrackSegment, wraps the AutoSegment parent's mechanism. Allows to gets the DataNegociate of either the segment or it's parent. - New: State::solveFullBlockages(), dedicated method to solves the case when all the allowed tracks of a segment are blocked, tries to moves up local segments and to break-up global ones. - New: RoutingEventLoop, a more sophisticated way to detect looping. Maintain a dynamic histogram of the last N (default 10) segments routeds, with the count of how many times they have occurred. If that count exeed 40, we *may* be facing a loop. - Change: In State::conflictSolve1, implement new policy. The global segments no more can be broken by local ones. The idea behind is that breaking a global on the request of a local will only produce more cluttering in the GCell. Globals must be keep straigth pass through, especially inside near-saturated GCells. Globals breaking however can occurs at another global's request. - Change: In TrackCost, implement the new policy about locals segments that cannot break globals segments. The sorting class now accept flags to modulate the sorting function. Two options avalaibles: IgnoreAxisWeigth (to uses for strap segments) and DiscardGlobals (to uses with locals). - Change: In TrackCost, the "distance to fixed" have now an upper bound of 50 lambdas (no need to be greater because it means it's outside the begin & en GCells). Take account not only of fixed segment, but also of placed segments which makes bound. - Bug: In Track::_check(), while calling each individual TrackSegment check, uses it as the *first* argument of the "or", otherwise it may not be called. - Bug: In ProtectRoutingPad, loop over segment Collections while modificating it was producing non-deterministic results. The fact that a collection must be not modificated while beeing iterated is becoming a more and more painful problem. --- kite/src/BuildPowerRails.cpp | 84 +++- kite/src/CMakeLists.txt | 2 + kite/src/Configuration.cpp | 27 +- kite/src/KiteEngine.cpp | 41 +- kite/src/NegociateWindow.cpp | 22 +- kite/src/ProtectRoutingPads.cpp | 147 ++---- kite/src/RoutingEvent.cpp | 726 +++++++++++++++++----------- kite/src/RoutingEventHistory.cpp | 16 +- kite/src/RoutingEventLoop.cpp | 94 ++++ kite/src/RoutingPlane.cpp | 2 +- kite/src/Track.cpp | 6 +- kite/src/TrackCost.cpp | 70 +-- kite/src/TrackElement.cpp | 7 +- kite/src/TrackFixedSegment.cpp | 8 +- kite/src/TrackSegment.cpp | 79 ++- kite/src/kite/DataNegociate.h | 6 +- kite/src/kite/NegociateWindow.h | 3 + kite/src/kite/RoutingEvent.h | 134 ++--- kite/src/kite/RoutingEventHistory.h | 3 - kite/src/kite/RoutingEventLoop.h | 93 ++++ kite/src/kite/TrackCost.h | 106 ++-- kite/src/kite/TrackElement.h | 20 +- kite/src/kite/TrackSegment.h | 19 +- 23 files changed, 1107 insertions(+), 608 deletions(-) create mode 100644 kite/src/RoutingEventLoop.cpp create mode 100644 kite/src/kite/RoutingEventLoop.h diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index d6479798..604fea56 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -73,6 +73,7 @@ namespace { using Hurricane::Technology; using Hurricane::DataBase; using CRL::AllianceFramework; + using Katabatic::ChipTools; using namespace Kite; @@ -327,6 +328,7 @@ namespace { public: Plane ( const Layer*, RoutingPlane* ); ~Plane (); + inline const Layer* getLayer () const; inline RoutingPlane* getRoutingPlane (); inline Constant::Direction getDirection () const; void merge ( const Box&, Net* ); @@ -596,6 +598,7 @@ namespace { } + inline const Layer* PowerRailsPlanes::Plane::getLayer () const { return _layer; } inline RoutingPlane* PowerRailsPlanes::Plane::getRoutingPlane () { return _routingPlane; } inline Constant::Direction PowerRailsPlanes::Plane::getDirection () const { return (Constant::Direction)_routingPlane->getDirection(); } @@ -749,16 +752,20 @@ namespace { , const Box& area , const Transformation& transformation ); + void ringAddToPowerRails (); virtual void doQuery (); inline void doLayout (); inline unsigned int getGoMatchCount () const; private: - AllianceFramework* _framework; - KiteEngine* _kite; - RoutingGauge* _routingGauge; - PowerRailsPlanes _powerRailsPlanes; - bool _isBlockagePlane; - unsigned int _goMatchCount; + AllianceFramework* _framework; + KiteEngine* _kite; + RoutingGauge* _routingGauge; + const ChipTools& _chipTools; + PowerRailsPlanes _powerRailsPlanes; + bool _isBlockagePlane; + vector _hRingSegments; + vector _vRingSegments; + unsigned int _goMatchCount; }; @@ -767,8 +774,11 @@ namespace { , _framework (AllianceFramework::get()) , _kite (kite) , _routingGauge (kite->getConfiguration()->getRoutingGauge()) + , _chipTools (kite->getChipTools()) , _powerRailsPlanes(kite) , _isBlockagePlane (false) + , _hRingSegments () + , _vRingSegments () , _goMatchCount (0) { setCell ( kite->getCell() ); @@ -802,6 +812,7 @@ namespace { { if ( not _powerRailsPlanes.getActivePlane() ) return; Query::doQuery (); + } @@ -844,6 +855,21 @@ namespace { ltrace(300) << " Merging PowerRail element: " << segment << endl; Box bb = segment->getBoundingBox ( basicLayer ); + + unsigned int depth = _routingGauge->getLayerDepth ( segment->getLayer() ); + + if ( _chipTools.isChip() + and ((depth == 2) or (depth == 3)) + and (segment->getWidth () == DbU::lambda( 12.0)) + and (segment->getLength() > DbU::lambda(200.0)) + and (_kite->getChipTools().getCorona().contains(bb)) ) { + switch ( depth ) { + case 2: _vRingSegments.push_back ( segment ); break; // M3 V. + case 3: _hRingSegments.push_back ( segment ); break; // M4 H. + } + return; + } + transformation.applyOn ( bb ); _powerRailsPlanes.merge ( bb, rootNet ); @@ -864,6 +890,51 @@ namespace { } + void QueryPowerRails::ringAddToPowerRails () + { + + if ( not _hRingSegments.empty() ) { + const RegularLayer* layer = dynamic_cast(_routingGauge->getRoutingLayer(3)); + setBasicLayer ( layer->getBasicLayer() ); + + DbU::Unit xmin = DbU::Max; + DbU::Unit xmax = DbU::Min; + vector boxes; + + for ( size_t i=0 ; i<_hRingSegments.size() ; ++i ) { + boxes.push_back ( _hRingSegments[i]->getBoundingBox() ); + xmin = std::min ( xmin, boxes.back().getXMin() ); + xmax = std::max ( xmax, boxes.back().getXMax() ); + } + + for ( size_t i=0 ; i<_hRingSegments.size() ; ++i ) { + _powerRailsPlanes.merge ( Box(xmin,boxes[i].getYMin(),xmax,boxes[i].getYMax()) + , _powerRailsPlanes.getRootNet(_hRingSegments[i]->getNet(),Path()) ); + } + } + + if ( not _vRingSegments.empty() ) { + const RegularLayer* layer = dynamic_cast(_routingGauge->getRoutingLayer(2)); + setBasicLayer ( layer->getBasicLayer() ); + + DbU::Unit ymin = DbU::Max; + DbU::Unit ymax = DbU::Min; + vector boxes; + + for ( size_t i=0 ; i<_vRingSegments.size() ; ++i ) { + boxes.push_back ( _vRingSegments[i]->getBoundingBox() ); + ymin = std::min ( ymin, boxes.back().getYMin() ); + ymax = std::max ( ymax, boxes.back().getYMax() ); + } + + for ( size_t i=0 ; i<_vRingSegments.size() ; ++i ) { + _powerRailsPlanes.merge ( Box(boxes[i].getXMin(),ymin,boxes[i].getXMax(),ymax) + , _powerRailsPlanes.getRootNet(_vRingSegments[i]->getNet(),Path()) ); + } + } + } + + void QueryPowerRails::rubberCallback ( Rubber* ) { } @@ -910,6 +981,7 @@ namespace Kite { query.setBasicLayer ( *iLayer ); query.doQuery (); } + query.ringAddToPowerRails (); query.doLayout (); cmess1 << " - " << query.getGoMatchCount() << " power rails elements found." << endl; diff --git a/kite/src/CMakeLists.txt b/kite/src/CMakeLists.txt index 59ce39dd..5d6d0931 100644 --- a/kite/src/CMakeLists.txt +++ b/kite/src/CMakeLists.txt @@ -22,6 +22,7 @@ kite/RoutingEvent.h kite/RoutingEventQueue.h kite/RoutingEventHistory.h + kite/RoutingEventLoop.h kite/RoutingPlane.h kite/NegociateWindow.h kite/Configuration.h @@ -45,6 +46,7 @@ RoutingEvent.cpp RoutingEventQueue.cpp RoutingEventHistory.cpp + RoutingEventLoop.cpp RoutingPlane.cpp BuildPowerRails.cpp ProtectRoutingPads.cpp diff --git a/kite/src/Configuration.cpp b/kite/src/Configuration.cpp index ebf07579..d82dd6f1 100644 --- a/kite/src/Configuration.cpp +++ b/kite/src/Configuration.cpp @@ -77,11 +77,12 @@ namespace Kite { threshold = 2*50; break; default: - threshold = 29*50; + threshold = 30*50; break; } - _globalMinBreaks[i] = DbU::lambda(Cfg::getParamInt(paramName.str(),threshold)->asInt()); + Cfg::getParamDouble(paramName.str())->setDouble(threshold); + _globalMinBreaks[i] = DbU::lambda (Cfg::getParamDouble(paramName.str())->asDouble()); } } @@ -239,9 +240,7 @@ namespace Kite { string Configuration::_getTypeName () const - { - return "Configuration"; - } + { return "Configuration"; } string Configuration::_getString () const @@ -258,6 +257,24 @@ namespace Kite { { Record* record = _base->_getRecord(); //record->add ( getSlot ( "_rg" , _rg ) ); + if ( record ) { + record->add ( getSlot("_edgeCapacityPercent",_edgeCapacityPercent) ); + record->add ( getSlot("_ripupCost" ,_ripupCost ) ); + record->add ( getSlot("_eventsLimit" ,_eventsLimit ) ); + record->add ( getSlot("_edgeCapacityPercent",_edgeCapacityPercent) ); + + record->add ( getSlot("_ripupLimits[StrapRipupLimit]" ,_ripupLimits[StrapRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[LocalRipupLimit]" ,_ripupLimits[LocalRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[GlobalRipupLimit]" ,_ripupLimits[GlobalRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[LongGlobalRipupLimit]",_ripupLimits[LongGlobalRipupLimit]) ); + + for ( size_t i=0 ; iadd ( DbU::getValueSlot(paramName.str(),&_globalMinBreaks[i]) ); + } + } return record; } diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index 8485bd40..84348df8 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -459,19 +459,23 @@ namespace Kite { //DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_soper_se(20)" ); //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_1m_dp_instaddbracry_sd_gi_1_21" ); + //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_1m_dp_addsub32_carith_se_pi_3_29" ); //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(26)" ); + //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.yoper_se(13)" ); //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.toper_se(5)" ); + //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.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)" ); //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.nextpc_rd(21)" ); //DebugSession::addToTrace ( getCell(), "addr_i(1)" ); //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_rd(1)" ); //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.otheri_sd(29)" ); - //DebugSession::addToTrace ( getCell(), "d_in_i(11)" ); + //DebugSession::addToTrace ( getCell(), "d_in_i(22)" ); //DebugSession::addToTrace ( getCell(), "ng_i" ); //DebugSession::addToTrace ( getCell(), "d_out_i(14)" ); //DebugSession::addToTrace ( getCell(), "d_out_i(19)" ); @@ -479,13 +483,33 @@ namespace Kite { //DebugSession::addToTrace ( getCell(), "dout_e_i(2)" ); //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.aux44" ); //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.na4_x1_11_sig" ); + //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.nxr2_x1_7_sig" ); //DebugSession::addToTrace ( getCell(), "mips_r3000_core.rsdnbr_sd(14)" ); - //DebugSession::addToTrace ( getCell(), "d_out_i(27)" ); + //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(0)" ); + //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(11)" ); + //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_rd(0)" ); + //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.no4_x1_7_sig" ); + //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.aux78" ); + //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)" ); createDetailedGrid (); buildPowerRails (); protectRoutingPads (); + Session::revalidate (); + if ( mode == LoadGlobalSolution ) { _knik->loadSolution (); } else { @@ -665,7 +689,7 @@ namespace Kite { bool coherency = true; coherency = coherency && KatabaticEngine::_check ( message ); for ( size_t i=0 ; i<_routingPlanes.size() ; i++ ) - coherency = _routingPlanes[i]->_check(overlap) && coherency; + coherency = _routingPlanes[i]->_check(overlap) and coherency; Katabatic::Session* ktbtSession = Session::base (); forEach ( Net*, inet, getCell()->getNets() ) { @@ -687,7 +711,7 @@ namespace Kite { } #if defined(CHECK_DATABASE) - //Session::getKiteEngine()->setInterrupt ( !coherency ); + //Session::getKiteEngine()->setInterrupt ( not coherency ); #endif return coherency; @@ -823,7 +847,10 @@ namespace Kite { { Record* record = KatabaticEngine::_getRecord (); - record->add ( getSlot ( "_routingPlanes", &_routingPlanes ) ); + if ( record ) { + record->add ( getSlot ( "_routingPlanes", &_routingPlanes ) ); + record->add ( getSlot ( "_configuration", _configuration ) ); + } return record; } diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index afebd87e..8f5a06bf 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -48,6 +48,7 @@ #include "kite/RoutingPlane.h" #include "kite/RoutingEventQueue.h" #include "kite/RoutingEventHistory.h" +#include "kite/RoutingEventLoop.h" #include "kite/NegociateWindow.h" #include "kite/KiteEngine.h" @@ -75,6 +76,7 @@ namespace { return; } + if ( cost.getInterval().getVMax() > intersect.getVMax() ) cost.setLeftOverlap(); if ( cost.getInterval().getVMin() < intersect.getVMin() ) cost.setRightOverlap(); @@ -92,6 +94,12 @@ namespace { } } + if ( segment->isGlobal() ) { + //if ( data->getState() >= DataNegociate::ConflictSolve1 ) { + cost.setOverlapGlobal(); + //} + } + // if ( data->getRipupCount() > 3 ) { // ltrace(200) << "Infinite cost from: " << segment << endl; // cost.setFixed (); @@ -164,6 +172,7 @@ namespace Kite { , _segments () , _eventQueue () , _eventHistory() + , _eventLoop (10,50) { } @@ -378,14 +387,15 @@ namespace Kite { while ( not _eventQueue.empty() and not isInterrupted() ) { RoutingEvent* event = _eventQueue.pop (); - event->process ( _eventQueue, _eventHistory ); + event->process ( _eventQueue, _eventHistory, _eventLoop ); if (tty::enabled()) { - cmess1 << " " << tty::cr; - cmess1.flush (); + cmess2.flush (); } else { cmess2 << " id:" + << RoutingEvent::getProcesseds() << setfill(' ') << "> @" + << DbU::getValueString(event->getSegment()->getAxis()) << " id:" << event->getSegment()->getId() << " " << event->getSegment()->getNet()->getName() << endl; @@ -410,7 +420,7 @@ namespace Kite { count++; event->setProcessed ( false ); event->setMode ( RoutingEvent::PostPack ); - event->process ( _eventQueue, _eventHistory ); + event->process ( _eventQueue, _eventHistory, _eventLoop ); if (tty::enabled()) { cmess1 << " getGCellGrid()->getGCellVector(); - getKiteEngine()->getGCellGrid()->setDensityMode ( Katabatic::GCellGrid::AverageHVDensity ); + getKiteEngine()->getGCellGrid()->setDensityMode ( Katabatic::GCellGrid::MaxHVDensity ); for ( size_t igcell=0 ; igcell<(*gcells).size() ; ++igcell ) { densityHistogram->addSample ( (*gcells)[igcell]->getDensity(), 0 ); } diff --git a/kite/src/ProtectRoutingPads.cpp b/kite/src/ProtectRoutingPads.cpp index 4041c40b..0c26fafb 100644 --- a/kite/src/ProtectRoutingPads.cpp +++ b/kite/src/ProtectRoutingPads.cpp @@ -85,28 +85,34 @@ namespace { if ( CatalogExtension::isPad(masterNet->getCell()) ) return; + vector segments; + forEach ( Segment*, isegment, masterNet->getSegments() ) { RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(isegment->getLayer()); - if ( plane == NULL ) { - continue; - } - - unsigned int direction = plane->getDirection(); - DbU::Unit wireWidth = plane->getLayerGauge()->getWireWidth(); - DbU::Unit delta = plane->getLayerGauge()->getHalfPitch() - + wireWidth/2 - - DbU::lambda(0.1); - DbU::Unit extension = isegment->getLayer()->getExtentionCap(); + if ( plane == NULL ) continue; if ( usedComponent == dynamic_cast(*isegment) ) continue; if ( not NetExternalComponents::isExternal(*isegment) ) continue; - //cinfo << "Protecting " << *isegment << endl; + //cerr << "Looking " << (void*)*isegment << ":" << *isegment << endl; + + segments.push_back ( *isegment ); + } + + for ( size_t i=0 ; igetRoutingPlaneByLayer(segments[i]->getLayer()); + unsigned int direction = plane->getDirection(); + DbU::Unit wireWidth = plane->getLayerGauge()->getWireWidth(); + DbU::Unit delta = plane->getLayerGauge()->getHalfPitch() + + wireWidth/2 + - DbU::lambda(0.1); + DbU::Unit extension = segments[i]->getLayer()->getExtentionCap(); + Box bb ( segments[i]->getBoundingBox() ); - Box bb ( (*isegment)->getBoundingBox() ); transformation.applyOn ( bb ); - - //cinfo << "bb: " << bb << endl; + cinfo << "bb: " << bb << endl; if ( direction == Constant::Horizontal ) { DbU::Unit axisMin = bb.getYMin() - delta; @@ -115,61 +121,14 @@ namespace { Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { Horizontal* segment = Horizontal::create ( rp->getNet() - , isegment->getLayer() + , segments[i]->getLayer() , track->getAxis() , wireWidth , bb.getXMin()+extension , bb.getXMax()-extension ); - // TrackElement* element = - TrackFixedSegment::create ( track, segment ); - //cinfo << " Rp Protect:" << track << "+" << element << endl; + TrackFixedSegment::create ( track, segment ); } - - // Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); - // for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { - // Point sourcePosition (bb.getXMin()+extension,track->getAxis()); - // Point targetPosition (bb.getXMax()-extension,track->getAxis()); - - // Katabatic::GCell* sourceGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( sourcePosition ); - // Katabatic::GCell* targetGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( targetPosition ); - - // cinfo << " S: " << sourceGCell << " from " << sourcePosition << endl; - // cinfo << " T: " << targetGCell << " from " << targetPosition << endl; - - // unsigned int segmentType - // = (sourceGCell == targetGCell) ? AutoSegment::Local : AutoSegment::Global; - - // AutoContact* source = AutoContact::fromRp ( sourceGCell - // , rp - // , rp->getLayer() - // , sourcePosition - // , DbU::lambda(1.0), DbU::lambda(1.0) - // , true - // ); - - // AutoContact* target = AutoContact::fromRp ( targetGCell - // , rp - // , rp->getLayer() - // , targetPosition - // , DbU::lambda(1.0), DbU::lambda(1.0) - // , true - // ); - - // AutoSegment* segment = AutoSegment::create ( source - // , target - // , Constant::Horizontal - // , segmentType - // , true - // , false - // ); - // segment->setLayer ( isegment->getLayer() ); - // segment->setFixed ( true ); - - // bool created = true; - // TrackElement* element = TrackSegment::create ( segment, track, created ); - // cinfo << " Rp Protect " << track << "+" << element << endl; - // } } else { DbU::Unit axisMin = bb.getXMin() - delta; DbU::Unit axisMax = bb.getXMax() + delta; @@ -177,63 +136,14 @@ namespace { Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { Vertical* segment = Vertical::create ( rp->getNet() - , isegment->getLayer() + , segments[i]->getLayer() , track->getAxis() , wireWidth , bb.getYMin()+extension , bb.getYMax()-extension ); - // TrackElement* element = - TrackFixedSegment::create ( track, segment ); - //cinfo << " Rp Protect:" << track << "+" << element << endl; + TrackFixedSegment::create ( track, segment ); } - - // Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); - // for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { - // cinfo << " Track Axis: " << DbU::getValueString(track->getAxis()) << endl; - - // Point sourcePosition (track->getAxis(),bb.getYMin()+extension); - // Point targetPosition (track->getAxis(),bb.getYMax()-extension); - - // Katabatic::GCell* sourceGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( sourcePosition ); - // Katabatic::GCell* targetGCell = Session::getKatabatic()->getGCellGrid()->getGCell ( targetPosition ); - - // cinfo << " S: " << sourceGCell << " from " << sourcePosition << endl; - // cinfo << " T: " << targetGCell << " from " << targetPosition << endl; - - // unsigned int segmentType - // = (sourceGCell == targetGCell) ? AutoSegment::Local : AutoSegment::Global; - - // AutoContact* source = AutoContact::fromRp ( sourceGCell - // , rp - // , rp->getLayer() - // , sourcePosition - // , DbU::lambda(1.0), DbU::lambda(1.0) - // , true - // ); - - // AutoContact* target = AutoContact::fromRp ( targetGCell - // , rp - // , rp->getLayer() - // , targetPosition - // , DbU::lambda(1.0), DbU::lambda(1.0) - // , true - // ); - - // AutoSegment* segment = AutoSegment::create ( source - // , target - // , Constant::Vertical - // , segmentType - // , true - // , false - // ); - // segment->setLayer ( isegment->getLayer() ); - // segment->setFixed ( true ); - - // bool created = true; - // TrackElement* element = TrackSegment::create ( segment, track, created ); - // cinfo << " Rp Protect: " << track << "+" << element << endl; - // } } } } @@ -257,11 +167,18 @@ namespace Kite { cmess1 << " o Protect external components not useds as RoutingPads." << endl; forEach ( Net*, inet, getCell()->getNets() ) { + // cerr << *inet << " isSupply():" << (*inet)->isSupply() + // << " " << (*inet)->getType() + // << endl; if ( (*inet)->isSupply() ) continue; + vector rps; forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) { - protectRoutingPad ( *irp ); + rps.push_back ( *irp ); } + + for ( size_t i=0 ; i #include #include +#include "vlsisapd/configuration/Configuration.h" #include "hurricane/Bug.h" #include "hurricane/DebugSession.h" #include "hurricane/Breakpoint.h" @@ -40,6 +41,7 @@ #include "kite/RoutingEvent.h" #include "kite/RoutingEventHistory.h" #include "kite/RoutingEventQueue.h" +#include "kite/RoutingEventLoop.h" #include "kite/NegociateWindow.h" #include "kite/Session.h" #include "kite/KiteEngine.h" @@ -169,6 +171,7 @@ namespace { using namespace std; using namespace Hurricane; using namespace Kite; + using Katabatic::GCell; // ------------------------------------------------------------------- @@ -219,18 +222,19 @@ namespace { class Cs1Candidate { public: - inline Cs1Candidate ( Track* track=NULL ); - inline Track* getTrack () const; - inline size_t getBegin () const; - inline size_t getEnd () const; - inline size_t getLength () const; - inline Interval getConflict ( size_t ); - inline DbU::Unit getBreakPos () const; - inline DbU::Unit getConflictLength () const; - inline void setBegin ( size_t ); - inline void setEnd ( size_t ); - inline void addConflict ( const Interval& ); - void consolidate (); + inline Cs1Candidate ( Track* track=NULL ); + inline Track* getTrack () const; + inline size_t getBegin () const; + inline size_t getEnd () const; + inline size_t getLength () const; + inline Interval getConflict ( size_t ); + inline Interval getLongestConflict () const; + inline DbU::Unit getBreakPos () const; + inline DbU::Unit getConflictLength () const; + inline void setBegin ( size_t ); + inline void setEnd ( size_t ); + inline void addConflict ( const Interval& ); + void consolidate (); public: friend inline bool operator< ( const Cs1Candidate&, const Cs1Candidate& ); private: @@ -238,32 +242,38 @@ namespace { size_t _begin; size_t _end; vector _conflicts; + Interval _longestConflict; DbU::Unit _breakPos; DbU::Unit _conflictLength; }; inline Cs1Candidate::Cs1Candidate ( Track* track ) - : _track (track) - , _begin (0) - , _end (0) - , _conflicts () - , _breakPos (0) - , _conflictLength(0) + : _track (track) + , _begin (0) + , _end (0) + , _conflicts () + , _longestConflict() + , _breakPos (0) + , _conflictLength (0) { } - inline Track* Cs1Candidate::getTrack () const { return _track; } - inline size_t Cs1Candidate::getBegin () const { return _begin; } - inline size_t Cs1Candidate::getEnd () const { return _end; } - inline size_t Cs1Candidate::getLength () const { return _conflicts.size(); } - inline DbU::Unit Cs1Candidate::getBreakPos () const { return _breakPos; } - inline void Cs1Candidate::setBegin ( size_t i ) { _begin=i; } - inline void Cs1Candidate::setEnd ( size_t i ) { _end=i; } + inline Track* Cs1Candidate::getTrack () const { return _track; } + inline size_t Cs1Candidate::getBegin () const { return _begin; } + inline size_t Cs1Candidate::getEnd () const { return _end; } + inline size_t Cs1Candidate::getLength () const { return _conflicts.size(); } + inline Interval Cs1Candidate::getLongestConflict () const { return _longestConflict; } + inline DbU::Unit Cs1Candidate::getBreakPos () const { return _breakPos; } + inline void Cs1Candidate::setBegin ( size_t i ) { _begin=i; } + inline void Cs1Candidate::setEnd ( size_t i ) { _end=i; } inline void Cs1Candidate::addConflict ( const Interval& conflict ) { _conflicts.push_back(conflict); _conflictLength += conflict.getSize(); + + if ( conflict.getSize() > _longestConflict.getSize() ) + _longestConflict = conflict; } inline Interval Cs1Candidate::getConflict ( size_t i ) @@ -274,7 +284,8 @@ namespace { inline bool operator< ( const Cs1Candidate& lhs, const Cs1Candidate& rhs ) { - DbU::Unit delta = lhs._conflicts.size() - rhs._conflicts.size(); + //DbU::Unit delta = lhs._conflicts.size() - rhs._conflicts.size(); + DbU::Unit delta = lhs._longestConflict.getSize() - rhs._longestConflict.getSize(); if ( delta < 0 ) return true; if ( delta > 0 ) return false; @@ -719,6 +730,7 @@ namespace { , PackingMode = (1<<12) , ToState = (1<<13) , ToRipupLimit = (1<<14) + , RipedByLocal = (1<<15) , SelfInsert = Self |Insert , SelfRipup = Self |Ripup , SelfRipupPerpand = Self |Ripup | Perpandicular @@ -727,7 +739,7 @@ namespace { , SelfRipupAndAxisHint = Self |Ripup | Perpandicular|EventLevel4| AxisHint , OtherRipup = Other|Ripup , OtherPushAside = Other|Ripup | Perpandicular|EventLevel3 - , OtherPacking = Other|Ripup | Perpandicular|PackingMode + , OtherPacking = Other|Ripup | Perpandicular|EventLevel4|PackingMode }; public: SegmentAction ( TrackElement* @@ -816,6 +828,8 @@ namespace { if ( _type & EventLevel3 ) eventLevel = 3; if ( _type & EventLevel4 ) eventLevel = 4; if ( _type & EventLevel5 ) eventLevel = 5; + event->setRipedByLocal ( _type&RipedByLocal ); + RoutingEvent* fork = event->reschedule ( queue, eventLevel ); if ( fork ) @@ -851,36 +865,38 @@ namespace { }; public: - State ( RoutingEvent* - , RoutingEventQueue& - , RoutingEventHistory& - ); - inline RoutingEvent* getEvent (); - inline RoutingEventQueue& getQueue (); - inline RoutingEventHistory& getHistory (); - inline unsigned int getState (); - inline DataNegociate* getData (); - inline Interval& getConstraint (); - inline Interval& getOptimal (); - inline vector& getCosts (); - inline TrackCost& getCost ( size_t ); - inline Track* getTrack ( size_t ); - inline size_t getBegin ( size_t ); - inline size_t getEnd ( size_t ); - inline void setState ( unsigned int ); - inline void addAction ( TrackElement* - , unsigned int type - , DbU::Unit axisHint=0 - , unsigned int toState =0 - ); - inline vector& getActions (); - bool doActions (); - inline void clearActions (); - bool insertInTrack ( size_t ); - bool conflictSolve1 (); - bool conflictSolve2 (); - bool localVsGlobal (); - bool slackenTopology ( TrackElement*, unsigned int flags=0 ); + State ( RoutingEvent* + , RoutingEventQueue& + , RoutingEventHistory& + ); + inline RoutingEvent* getEvent (); + inline RoutingEventQueue& getQueue (); + inline RoutingEventHistory& getHistory (); + inline unsigned int getState (); + inline DataNegociate* getData (); + inline Interval& getConstraint (); + inline Interval& getOptimal (); + inline vector& getCosts (); + inline TrackCost& getCost ( size_t ); + inline Track* getTrack ( size_t ); + inline size_t getBegin ( size_t ); + inline size_t getEnd ( size_t ); + inline void setState ( unsigned int ); + inline void addAction ( TrackElement* + , unsigned int type + , DbU::Unit axisHint=0 + , unsigned int toState =0 + ); + inline vector& getActions (); + bool doActions (); + inline void clearActions (); + bool insertInTrack ( size_t ); + bool conflictSolve1_v1a (); + bool conflictSolve1_v1b (); + bool conflictSolve1_v2 (); + bool conflictSolve2 (); + bool slackenTopology ( unsigned int flags=0 ); + bool solveFullBlockages (); private: RoutingEvent* _event; @@ -901,14 +917,15 @@ namespace { class Manipulator { public: - enum { ToRipupLimit = 0x01 - , AllowExpand = 0x02 - , NoExpand = 0x04 - , PerpandicularsFirst = 0x08 - , ToMoveUp = 0x10 - , AllowLocalMoveUp = 0x20 - , AllowTerminalMoveUp = 0x40 - , NoDoglegReuse = 0x80 + enum { ToRipupLimit = 0x001 + , AllowExpand = 0x002 + , NoExpand = 0x004 + , PerpandicularsFirst = 0x008 + , ToMoveUp = 0x010 + , AllowLocalMoveUp = 0x020 + , AllowTerminalMoveUp = 0x040 + , AllowShortPivotUp = 0x080 + , NoDoglegReuse = 0x100 }; enum { LeftAxisHint=1, RightAxisHint=2 }; enum { HasNextRipup=0x2 }; @@ -936,6 +953,7 @@ namespace { bool desalignate (); bool slacken (); bool pivotUp (); + bool pivotDown (); bool moveUp ( unsigned int flags=0 ); bool makeDogLeg (); bool makeDogLeg ( DbU::Unit ); @@ -1049,7 +1067,13 @@ namespace { _state = EmptyTrackList; } - sort ( _costs.begin(), _costs.end() ); + unsigned int flags = 0; + flags |= (segment->isStrap()) ? TrackCost::IgnoreAxisWeight : 0; + flags |= (segment->isLocal() and (_data->getState() < DataNegociate::Minimize)) + ? TrackCost::DiscardGlobals : 0; + + sort ( _costs.begin(), _costs.end(), TrackCost::Compare(flags) ); + size_t i=0; for ( ; (i<_costs.size()) and _costs[i].isFree() ; i++ ); _event->setTracksFree ( i ); @@ -1090,7 +1114,10 @@ namespace { ltrace(200) << "State::doActions() - " << _actions.size() << endl; bool ripupOthersParallel = false; + bool ripedByLocal = getEvent()->getSegment()->isLocal(); + for ( size_t i=0 ; i<_actions.size() ; i++ ) { + if ( ripedByLocal ) _actions[i].setFlag ( SegmentAction::RipedByLocal ); if ( _actions[i].getType() & SegmentAction::OtherRipup ) { ripupOthersParallel = true; } @@ -1211,12 +1238,9 @@ namespace { } - bool State::conflictSolve1 () + bool State::conflictSolve1_v2 () { -#define OLD_conflictSolve1 1 - -#ifdef NEW_conflictSolve1 - ltrace(200) << "State::conflictSolve1()" << endl; + ltrace(200) << "State::conflictSolve1_v2()" << endl; ltracein(200); Interval constraints; @@ -1262,7 +1286,7 @@ namespace { Interval uside; size_t idogleg = 0; for ( size_t igcell=0 ; igcellgetUSide(segment->getDirection(),true); + uside = gcells[igcell]->getUSide(segment->getDirection()); ltrace(200) << "| " << gcells[igcell] << " uside: " << uside << endl; if ( uside.contains(doglegs[idogleg]) ) { @@ -1294,19 +1318,21 @@ namespace { ltraceout(200); return true; -#endif // NEW_conflictSolve1 + } -#ifdef OLD_conflictSolve1 + + bool State::conflictSolve1_v1a () + { bool success = false; Interval constraints; vector candidates; TrackElement* segment = _event->getSegment(); - bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); + bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); // MARK 1 unsigned int relaxFlags = Manipulator::NoDoglegReuse | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand : Manipulator::NoExpand); - ltrace(200) << "State::conflictSolve1()" << endl; + ltrace(200) << "State::conflictSolve1_v1a()" << endl; ltrace(200) << "| Candidates Tracks: " << endl; segment->base()->getConstraints ( constraints ); @@ -1364,13 +1390,6 @@ namespace { sort ( candidates.begin(), candidates.end() ); - // if ( not candidates.empty() ) { - // ltrace(200) << "Trying l:" << candidates[0].getLength() - // << " " << candidates[0].getTrack() << endl; - - // success = Manipulator(segment,*this).makeDogLeg ( candidates[0].getBreakPos() ); - // } - for ( size_t icandidate=0 ; icandidategetSegment(candidates[icandidate].getBegin()); // if ( other->isGlobal() and other->canMoveUp(1.0) ) { - // ltrace(200) << "conflictSolve1() - One conflict, other move up [" + // ltrace(200) << "conflictSolve1_v1a() - One conflict, other move up [" // << candidates[icandidate].getBegin() << "]" << endl; // if ( (success = other->moveUp()) ) break; // } if ( other->isGlobal() ) { - ltrace(200) << "conflictSolve1() - One conflict, other move up [" + ltrace(200) << "conflictSolve1_v1a() - One conflict, other move up [" << candidates[icandidate].getBegin() << "]" << endl; if ( (success = Manipulator(other,*this).moveUp()) ) break; } - ltrace(200) << "conflictSolve1() - One conflict, relaxing self" << endl; + ltrace(200) << "conflictSolve1_v1a() - One conflict, relaxing self" << endl; if ( Manipulator(segment,*this).relax(overlap0,relaxFlags) ) { success = true; @@ -1412,12 +1431,12 @@ namespace { } if ( candidates[icandidate].getLength() == 2 ) { - ltrace(200) << "conflictSolve1() - Two conflict, relaxing self" << endl; + ltrace(200) << "conflictSolve1_v1a() - Two conflict, relaxing self" << endl; Interval overlap1 = candidates[icandidate].getConflict(1); // Ugly: hard-coded half GCell side. if ( overlap1.getVMin() - overlap0.getVMax() < DbU::lambda(5.0) ) { - ltrace(200) << "conflictSolve1() - Too narrow spacing: " + ltrace(200) << "conflictSolve1_v1a() - Too narrow spacing: " << DbU::getValueString(overlap1.getVMin() - overlap0.getVMax()) << endl; continue; } @@ -1442,12 +1461,140 @@ namespace { unsigned int depth = Session::getConfiguration()->getRoutingGauge()->getLayerDepth(segment->getLayer()); if ( not success ) { + ltrace(200) << "Try to break " + << DbU::getValueString(segment->getLength()) + << " >= " << DbU::getValueString(Session::getConfiguration()->getGlobalMinBreak(depth)) + << endl; if ( (segment->getLength() >= Session::getConfiguration()->getGlobalMinBreak(depth)) ) { ltrace(200) << "Long global wire, break in the middle." << endl; Interval span; segment->getCanonical ( span ); success = Manipulator(segment,*this).makeDogLeg ( span.getCenter() ); + if ( success ) { + TrackElement* segment1 = Session::lookup ( Session::getDogLegs()[2] ); + if ( segment1 ) Manipulator(segment1,*this).pivotDown (); + Manipulator(segment,*this).pivotDown (); + } + } + } + + return success; + } + + + bool State::conflictSolve1_v1b () + { + bool success = false; + Interval constraints; + vector candidates; + TrackElement* segment = _event->getSegment(); + bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); // MARK 1 + unsigned int relaxFlags = Manipulator::NoDoglegReuse + | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand + : Manipulator::NoExpand); + + ltrace(200) << "State::conflictSolve1_v1b()" << endl; + ltrace(200) << "| Candidates Tracks: " << endl; + + segment->base()->getConstraints ( constraints ); + Interval overlap = segment->getCanonicalInterval(); + RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer()); + Track* track = plane->getTrackByPosition(constraints.getVMin(),Constant::Superior); + + for ( ; track->getAxis() <= constraints.getVMax() ; track = track->getNext() ) { + candidates.push_back ( Cs1Candidate(track) ); + + size_t begin; + size_t end; + TrackElement* other; + Net* otherNet = NULL; + Interval otherOverlap; + bool otherIsGlobal = false; + + track->getOverlapBounds ( overlap, begin, end ); + candidates.back().setBegin ( begin ); + candidates.back().setEnd ( end ); + + ltrace(200) << "* " << track << " [" << begin << ":" << end << "]" << endl; + + for ( ; (begin < end) ; begin++ ) { + other = track->getSegment(begin); + + if ( other->getNet() == segment->getNet() ) { + ltrace(200) << " | " << begin << " Same net: " << " " << other << endl; + continue; + } + if ( not other->getCanonicalInterval().intersect(overlap) ) { + ltrace(200) << " | " << begin << " No Conflict: " << " " << other << endl; + if ( otherNet == NULL ) candidates.back().setBegin ( begin+1 ); + continue; + } + ltrace(200) << " | " << begin << " Conflict: " << " " << other << endl; + + if ( otherNet != other->getNet() ) { + if ( otherNet ) { + if ( otherIsGlobal ) { + candidates.back().addConflict ( otherOverlap ); + ltrace(200) << " | Other overlap G: " << otherOverlap << endl; + } else { + ltrace(200) << " | Other overlap L: " << otherOverlap << " ignored." << endl; + } + } + otherNet = other->getNet(); + otherOverlap = other->getCanonicalInterval(); + otherIsGlobal = otherIsGlobal or other->isGlobal(); + } else { + otherOverlap.merge(other->getCanonicalInterval()); + otherIsGlobal = otherIsGlobal or other->isGlobal(); + } + } + if ( not otherOverlap.isEmpty() ) { + if ( otherIsGlobal ) { + candidates.back().addConflict ( otherOverlap ); + ltrace(200) << " | Other overlap G: " << otherOverlap << endl; + } else { + ltrace(200) << " | Other overlap L: " << otherOverlap << " ignored." << endl; + } + } + + candidates.back().consolidate(); + } + + sort ( candidates.begin(), candidates.end() ); + + for ( size_t icandidate=0 ; icandidategetSegment(overlap.getCenter()); + if ( not other ) { + cerr << Error("conflictSolve1_v1b(): No segment under overlap center.") << endl; + continue; + } + + if ( other->isGlobal() ) { + ltrace(200) << "conflictSolve1_v1b() - Conflict with global, other move up" << endl; + if ( (success = Manipulator(other,*this).moveUp()) ) break; + } + + ltrace(200) << "conflictSolve1_v1b() - Relaxing self" << endl; + + if ( Manipulator(segment,*this).relax(overlap0,relaxFlags) ) { + success = true; + break; + } else { + if ( not canMoveUp + and (relaxFlags != Manipulator::NoExpand) + and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) { + ltrace(200) << "Cannot move up but successful narrow breaking." << endl; + success = true; + break; + } } } @@ -1459,125 +1606,68 @@ namespace { } return success; -#endif // OLD_conflictSolve1 } - bool State::localVsGlobal () + bool State::solveFullBlockages () { - ltrace(200) << "State::localVsGlobal()" << endl; + bool success = false; + bool blocked = (getCosts().size() > 0); + TrackElement* segment = getEvent()->getSegment(); + + ltrace(200) << "State::solveFullBlockages: " << " " << segment << endl; ltracein(200); - bool success = false; - Interval constraint = _event->getConstraints(); - TrackElement* segment = _event->getSegment(); - Interval overlap = segment->getCanonicalInterval(); - vector candidates; - //Interval uside = segment->getGCell()->getUSide(segment->getDirection(),true); - Interval uside = overlap; + for ( size_t itrack=0 ; itrackisLocal() ) { + success = Manipulator(segment,*this).pivotUp(); + if ( not success ) { + ltrace(200) << "Tightly constrained local segment overlapping a blockage, move up." << endl; + ltrace(200) << segment << endl; + success = Manipulator(segment,*this).moveUp + (Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp); + } + } else { + Interval overlap = segment->getCanonicalInterval(); + size_t begin; + size_t end; - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer()); - forEach ( Track*, itrack, Tracks_Range::get(plane,constraint)) { - ltrace(200) << "| " << (*itrack) << " - " << endl; + getCost(0).getTrack()->getOverlapBounds ( overlap, begin, end ); + for ( ; begingetSegment(begin); + Interval otherOverlap = other->getCanonicalInterval(); - size_t begin; - size_t end; - TrackElement* candidate = NULL; - Net* otherNet = NULL; - Interval otherOverlap; - unsigned int weight = 0; - size_t terminals = 0; + if ( other->getNet() == segment->getNet() ) continue; + if ( not otherOverlap.intersect(overlap) ) continue; - itrack->getOverlapBounds ( overlap, begin, end ); - for ( ; (begin < end) ; begin++ ) { - TrackElement* other = itrack->getSegment(begin); - - if ( other->getNet() == segment->getNet() ) continue; - if ( not other->getCanonicalInterval().intersect(overlap) ) continue; - if ( not other->isGlobal() ) { candidate = NULL; break; } - ltrace(200) << "| Conflict: " << begin << " " << other << endl; - - if ( otherNet == NULL ) { - otherNet = other->getNet(); - otherOverlap = other->getCanonicalInterval(); - candidate = other; - - itrack->getTerminalWeight ( uside, otherNet, terminals, weight ); - - // if ( (other->base()->getAutoSource()->getAnchor() != NULL) - // and (overlap.contains(otherOverlap.getVMin())) ) - // ++terminals; - - // if ( (other->base()->getAutoTarget()->getAnchor() != NULL) - // and (overlap.contains(otherOverlap.getVMax())) ) - // ++terminals; - - ltrace(200) << "> Candidate " << candidate << endl; - } else { - if ( other->getNet() == otherNet ) { - Interval otherCanonical = other->getCanonicalInterval(); - if ( otherOverlap.intersect(otherCanonical) ) { - otherOverlap.merge(otherCanonical); - - // if ( (other->base()->getAutoSource()->getAnchor() != NULL) - // and (overlap.contains(otherCanonical.getVMin())) ) - // ++terminals; - - // if ( (other->base()->getAutoTarget()->getAnchor() != NULL) - // and (overlap.contains(otherCanonical.getVMax())) ) - // ++terminals; - - continue; - } - } else { - ltrace(200) << "> Reject candidate " << candidate << endl; - candidate = NULL; + ltrace(200) << "| " << begin << " Blockage conflict: " << " " << other << endl; + if ( (success = Manipulator(segment,*this).relax + (otherOverlap,Manipulator::NoDoglegReuse|Manipulator::NoExpand)) ) { break; } } } - - if ( candidate ) { - ltrace(200) << "> Accept candidate " << candidate << endl; - candidates.push_back ( LvGCandidate(candidate,otherOverlap,terminals) ); - } - } - - if ( candidates.empty() ) { - ltraceout(200); - return false; - } - - sort ( candidates.begin(), candidates.end(), LvGCandidate::Compare() ); - for ( size_t i=0 ; igetNet(), 200 ); - + TrackElement* segment = getEvent()->getSegment(); bool success = false; bool blocked = false; bool repush = true; @@ -1585,13 +1675,14 @@ namespace { unsigned int nextState = data->getState(); unsigned int actionFlags = SegmentAction::SelfInsert|SegmentAction::EventLevel5; + DebugSession::open ( segment->getNet(), 200 ); ltrace(200) << "Slacken Topology for " << segment->getNet() << " " << segment << endl; ltracein(200); if ( (not segment) or (not data) ) { ltraceout(200); DebugSession::close(); return false; } - if ( segment == _event->getSegment() ) _event->resetInsertState(); + _event->resetInsertState(); data->resetRipupCount (); // Normal cases. @@ -1605,7 +1696,9 @@ namespace { if ( success ) break; case DataNegociate::Desalignate: case DataNegociate::Minimize: - nextState = DataNegociate::LocalVsGlobal; + if ( data->getStateCount() >= 2 ) { + nextState = DataNegociate::MaximumSlack; + } success = Manipulator(segment,*this).minimize(); if ( success ) break; case DataNegociate::DogLeg: @@ -1613,15 +1706,6 @@ namespace { case DataNegociate::ConflictSolve1: case DataNegociate::ConflictSolve2: case DataNegociate::MoveUp: - case DataNegociate::LocalVsGlobal: - if ( not (flags & NoRecursive) ) { - if ( (success = localVsGlobal()) ) { - nextState = DataNegociate::LocalVsGlobal; - if ( data->getStateCount() >= 1 ) - nextState = DataNegociate::MaximumSlack; - break; - } - } case DataNegociate::MaximumSlack: case DataNegociate::Unimplemented: nextState = DataNegociate::Unimplemented; @@ -1663,23 +1747,14 @@ namespace { break; } case DataNegociate::MoveUp: - nextState = DataNegociate::LocalVsGlobal; + nextState = DataNegociate::MaximumSlack; success = Manipulator(segment,*this).moveUp(); if ( success ) break; - case DataNegociate::LocalVsGlobal: - if ( not (flags & NoRecursive) ) { - if ( (success = localVsGlobal()) ) { - nextState = DataNegociate::LocalVsGlobal; - if ( data->getStateCount() >= 1 ) - nextState = DataNegociate::MaximumSlack; - break; - } - } case DataNegociate::MaximumSlack: if ( segment->isSlackenStrap() ) { if ( (nextState < DataNegociate::MaximumSlack) or (data->getStateCount() < 2) ) { nextState = DataNegociate::MaximumSlack; - success = conflictSolve1 (); + success = conflictSolve1_v1b (); if ( success ) break; } } @@ -1693,48 +1768,11 @@ namespace { success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); } - // Special case: all tracks are overlaping a blockage. if ( not success and (nextState == DataNegociate::Unimplemented) and segment->isSlackened() ) { - blocked = (getCosts().size() > 0); - for ( size_t itrack=0 ; itrackgetSegment()->base()->getConstraints ( nativeConstraints ); - - //if ( nativeConstraints.getSize() < DbU::lambda(5.0) ) { - // blocked = true; - success = Manipulator(segment,*this).pivotUp(); - if ( not success ) { - cerr << "BLOCKAGE MOVE UP " << segment << endl; - success = Manipulator(segment,*this).moveUp - (Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp); - } - if ( not success ) { - cerr << "[ERROR] Tighly constrained segment overlapping a blockage." << endl; - ltrace(200) << "Segment is hard blocked, bypass to Unimplemented." << endl; - nextState = DataNegociate::Unimplemented; - } - //} - } + solveFullBlockages (); } - - // LOOPING. - // if ( not success - // and (nextState == DataNegociate::Unimplemented) - // and segment->isSlackened() ) { - // ltrace(200) << "Last chance on slackened" << endl; - // segment->base()->setSlackened ( false ); - // success = Manipulator(segment,*this).makeDogLeg(); - // nextState = DataNegociate::MaximumSlack; - // } } else { // Global TrackElement State Machine. switch ( data->getState() ) { @@ -1759,7 +1797,7 @@ namespace { } case DataNegociate::MoveUp: ltrace(200) << "Global, State: MoveUp." << endl; - if ( (success = Manipulator(segment,*this).moveUp()) ) { + if ( (success = Manipulator(segment,*this).moveUp(Manipulator::AllowShortPivotUp)) ) { break; } nextState = DataNegociate::ConflictSolve1; @@ -1768,13 +1806,15 @@ namespace { case DataNegociate::ConflictSolve2: ltrace(200) << "Global, State: ConflictSolve1 or ConflictSolve2." << endl; if ( not (flags & NoRecursive) ) { - if ( (success = conflictSolve1 ()) ) { - if ( segment->canMoveUp(0.0) ) + if ( (success = conflictSolve1_v1b()) ) { + if ( segment->canMoveUp(1.0) ) // MARK 1 nextState = DataNegociate::MoveUp; else { if ( data->getStateCount() > 3 ) nextState = DataNegociate::MaximumSlack; } + if ( segment->getDataNegociate()->getState() < DataNegociate::ConflictSolve1 ) + nextState = segment->getDataNegociate()->getState(); break; } } @@ -1789,6 +1829,13 @@ namespace { if ( data->getStateCount() < 6 ) success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); } + + // Special case: all tracks are overlaping a blockage. + if ( not success + and (nextState == DataNegociate::Unimplemented) + and segment->isSlackened() ) { + solveFullBlockages (); + } } } @@ -2086,7 +2133,7 @@ namespace { size_t imindensity = 0; for ( size_t iexpand=1 ; iexpand < iminconflict ; iexpand++ ) { - if ( not _segment->canDogLegAt(gcells[iexpand],true) ) continue; + if ( not _segment->canDogLegAt(gcells[iexpand],TrackElement::AllowDoglegReuse) ) continue; ltrace(200) << "Density " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << " " << gcells[iexpand]->getDensity(depth) << endl; @@ -2102,7 +2149,7 @@ namespace { if ( imaxconflict < gcells.size() ) { size_t imindensity = imaxconflict; for ( size_t iexpand=imaxconflict+1; iexpand < gcells.size() ; iexpand++ ) { - if ( not _segment->canDogLegAt(gcells[iexpand],true) ) continue; + if ( not _segment->canDogLegAt(gcells[iexpand],TrackElement::AllowDoglegReuse) ) continue; ltrace(200) << "Density " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << " " << gcells[iexpand]->getDensity(depth) << endl; @@ -2316,10 +2363,12 @@ namespace { ltrace(200) << "Dogleg has no RoutingEvent yet." << endl; } + // This cases seems never to occurs. const vector& doglegs = Session::getDogLegs(); for ( size_t i=0 ; igetTrack() and track ) { + ltrace(200) << "Direct Track insert of: " << segment << endl; Session::addInsertEvent ( segment, track ); } } @@ -2344,6 +2393,27 @@ namespace { break; } + if ( _segment->isLocal() ) { + ltrace(200) << "Reset state of: " << _segment << endl; + _segment->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); + } else { + ltrace(200) << "No state reset: " << _segment << endl; + } + + if ( (not doglegReuse1) and segment1 and segment1->isLocal() ) { + ltrace(200) << "Reset state of: " << segment1 << endl; + segment1->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); + } + + if ( (not doglegReuse2) and segment2 and segment2->isLocal() ) { + ltrace(200) << "Reset state of: " << segment2 << endl; + segment2->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); + } + + // if ( _segment ) Manipulator(_segment,_S).pivotDown (); + // if ( segment1 ) Manipulator(segment1,_S).pivotDown (); + // if ( segment2 ) Manipulator(segment2,_S).pivotDown (); + ltraceout(200); return success; } @@ -2429,6 +2499,7 @@ namespace { 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; } @@ -2782,6 +2853,19 @@ namespace { } + bool Manipulator::pivotDown () + { + ltrace(200) << "Manipulator::pivotDown() " << _segment << endl; + + if ( _segment->isFixed () ) return false; + if ( _segment->isStrap () ) return false; + if ( not _segment->canPivotDown(2.0) ) return false; + + _segment->moveDown (); + return true; + } + + bool Manipulator::moveUp ( unsigned int flags ) { ltrace(200) << "Manipulator::moveUp() " << _segment << endl; @@ -2795,11 +2879,15 @@ namespace { if ( _segment->isLocal() ) { if ( not _segment->canPivotUp(0.5) ) return false; } else { - if ( _segment->getLength() < DbU::lambda(/*100.0*/50.0) ) return false; - if ( not _segment->canMoveUp(1.0,kflags) ) return false; + if ( _segment->getLength() < DbU::lambda(100.0) ) { + if ( not (flags & AllowShortPivotUp) ) return false; + if ( not _segment->canPivotUp(2.0) ) return false; + } + if ( not _segment->canMoveUp(1.0,kflags) ) return false; // MARK 1 } - } else - if ( not _segment->canMoveUp(1.0,kflags) ) return false; + } else { + if ( not _segment->canMoveUp(1.0,kflags) ) return false; // MARK 1 + } #if DISABLED ltrace(200) << "| Repack Tracks: " << endl; @@ -3159,6 +3247,7 @@ namespace Kite { using Hurricane::ForEachIterator; using Hurricane::Net; using Hurricane::Layer; + using Katabatic::GCell; // ------------------------------------------------------------------- @@ -3294,6 +3383,7 @@ namespace Kite { , _canHandleConstraints(false) , _minimized (false) , _forceToHint (false) + , _ripedByLocal (false) , _segment (segment) , _axisHistory (segment->getAxis()) , _axisHint (segment->getAxis()) @@ -3323,7 +3413,7 @@ namespace Kite { invalidate ( true ); ltrace(180) << "create: " << (void*)this << ":" << this << endl; - ltrace(200) << "Initial setAxisHint @" << DbU::getValueString(_axisHint) << endl; + ltrace(200) << "Initial setAxisHint @" << DbU::getValueString(getAxisHint()) << endl; if ( _segment->getTrack() ) { cerr << Bug("RoutingEvent::create() - TrackElement is already inserted in a Track." @@ -3414,8 +3504,24 @@ namespace Kite { } - long RoutingEvent::getAxisWeight ( DbU::Unit axis ) const - { return abs(axis - _axisHint); } + void RoutingEvent::cacheAxisHint () + { + TrackElement* parent = _segment->getParent(); + if ( not parent ) return; + + RoutingEvent* parentEvent = parent->getDataNegociate()->getRoutingEvent(); + if ( parentEvent == this ) { + cerr << Error("RoutingEvent::getAxisHint(): Parentage loop between\n" + " this :%p:%s\n parent:%p:%s" + ,_segment->base(),getString(_segment->base()).c_str() + ,parent ->base(),getString(parent ->base()).c_str() + ) << endl; + _axisHint = parent->getAxis(); + return; + } + _axisHint = (parentEvent) ? parentEvent->getAxisHint() : parent->getAxis (); + return; + } RoutingEvent* RoutingEvent::reschedule ( RoutingEventQueue& queue, unsigned int eventLevel ) @@ -3465,8 +3571,66 @@ namespace Kite { } - void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history ) + void RoutingEvent::process ( RoutingEventQueue& queue + , RoutingEventHistory& history + , RoutingEventLoop& loop + ) { + loop.update ( _segment->getId() ); + if ( loop.isLooping() ) { + if ( ltracelevel() > 200 ) { + + cerr << Error("Loop detected: %s.\n Enabling trace (level:200)" + ,_getString().c_str()) << endl; + //ltracelevel ( 200 ); + //Cfg::getParamInt("misc.traceLevel")->setInt ( 200, Cfg::Parameter::CommandLine ); + + const vector& elements = loop.getElements(); + for ( size_t i=0 ; i 500 ) { + cerr << Error("Loop detected, removing event %s.",_getString().c_str()) << endl; + //Cfg::getParamInt("misc.traceLevel")->setInt ( 1000, Cfg::Parameter::CommandLine ); + //ltracelevel ( 1000 ); + + loop.erase ( _segment->getId() ); + setState ( DataNegociate::Unimplemented ); + + ostringstream message; + message << "Kite has detected a loop between the following Segments:\n"; + + const vector& elements = loop.getElements(); + for ( size_t i=0 ; i"; + + throw Error(message.str().c_str()); + } +#else + loop.erase ( _segment->getId() ); + setState ( DataNegociate::Unimplemented ); + + ostringstream message; + message << "Kite has detected a loop between the following Segments:\n"; + + const vector& elements = loop.getElements(); + for ( size_t i=0 ; i"; + + cerr << message << endl; +#endif + } + DebugSession::open ( _segment->getNet(), 190 ); #if defined(CHECK_DETERMINISM) @@ -3534,14 +3698,6 @@ namespace Kite { State S ( this, queue, history ); - if ( S.getHistory().looping() ) { - cerr << Error("RoutingEvent::process() - Simple Loop detection triggered.") << endl; - - setState ( DataNegociate::Unimplemented ); - S.getHistory().dump ( cerr, 40 ); - return; - } - if ( S.getState() == State::MissingData ) { cerr << Error("RoutingEvent::process() - Missing datas.") << endl; return; @@ -3556,18 +3712,18 @@ namespace Kite { ltrace(200) << "| " << S.getCost(itrack) << endl; itrack = 0; - if ( isForcedToHint() ) { - // Try to honor the forced axis hint. - bool hintFound = false; - for ( ; itrack < S.getCosts().size() ; itrack++ ) { - if ( S.getCost(itrack).getTrack()->getAxis() == _axisHint ) { - hintFound = true; - break; - } - } - if ( not hintFound ) itrack = 0; - ltrace(200) << "Forcing to hint Track: " << itrack << endl; - } + // if ( isForcedToHint() ) { + // // Try to honor the forced axis hint. + // bool hintFound = false; + // for ( ; itrack < S.getCosts().size() ; itrack++ ) { + // if ( S.getCost(itrack).getTrack()->getAxis() == getAxisHint() ) { + // hintFound = true; + // break; + // } + // } + // if ( not hintFound ) itrack = 0; + // ltrace(200) << "Forcing to hint Track: " << itrack << endl; + // } if ( Manipulator(_segment,S).canRipup() ) { if ( S.getCosts().size() and S.getCost(itrack).isFree() ) { @@ -3580,6 +3736,13 @@ namespace Kite { Session::addInsertEvent ( _segment, S.getCost(itrack).getTrack() ); 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 ); + } } else { // Do ripup. if ( S.getState() == State::EmptyTrackList ) { @@ -3587,6 +3750,7 @@ namespace Kite { } else { if ( Manipulator(_segment,S).canRipup(Manipulator::HasNextRipup)) { for ( itrack=0 ; itrackgetSegment() == _events.back()->getSegment()) ) - _identicals++; - else - _identicals = 0; - - _events.push_back(event); - -// if ( _identicals > 30 ) { -// dump ( cerr, 40 ); -// throw Error("RoutingEventHistory::push(): More than 30 identicals events, we are looping."); -// } - } + { _events.push_back(event); } void RoutingEventHistory::clear () @@ -103,7 +90,6 @@ namespace Kite { for ( size_t i=0 ; i < _events.size() ; i++ ) _events[i]->destroy(); _events.clear (); - _identicals = 0; } diff --git a/kite/src/RoutingEventLoop.cpp b/kite/src/RoutingEventLoop.cpp new file mode 100644 index 00000000..8d9d9ba5 --- /dev/null +++ b/kite/src/RoutingEventLoop.cpp @@ -0,0 +1,94 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2010, 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 | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./RoutingEventLoop.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include "kite/RoutingEvent.h" +#include "kite/RoutingEventLoop.h" + + +namespace Kite { + + using std::cerr; + using std::endl; + using std::vector; + using std::stable_sort; + + + RoutingEventLoop::RoutingEventLoop ( size_t depth, int countLimit ) + : _elements () + , _depth (depth) + , _maxCount (0) + , _countLimit(countLimit) + , _isLooping (false) + { } + + + void RoutingEventLoop::update ( size_t id ) + { + vector::iterator ielement = _elements.begin(); + for ( ; ielement != _elements.end() ; ++ielement ) { + if ( (*ielement)._id == id ) { + // Increment an already present element. + (*ielement)._count += 1; + (*ielement)._timestamp = RoutingEvent::getProcesseds(); + _maxCount = std::max ( _maxCount, (*ielement)._count ); + + if ( _maxCount > _countLimit ) _isLooping = true; + break; + } + } + + // The Event was not found. + if ( ielement == _elements.end() ) { + if ( _elements.size() >= _depth ) _elements.pop_back (); + _elements.push_back ( Element(id,RoutingEvent::getProcesseds()) ); + } + + stable_sort ( _elements.begin(), _elements.end(), CompareByTimestamp() ); + } + + + void RoutingEventLoop::erase ( size_t id ) + { + vector::iterator ielement = _elements.begin(); + for ( ; ielement != _elements.end() ; ++ielement ) { + if ( (*ielement)._id == id ) { + _elements.erase ( ielement ); + break; + } + } + + _maxCount = 0; + ielement = _elements.begin(); + for ( ; ielement != _elements.end() ; ++ielement ) { + _maxCount = std::max ( _maxCount, (*ielement)._count ); + } + + _isLooping = (_maxCount > _countLimit); + } + + +} // End of Kite namespace. diff --git a/kite/src/RoutingPlane.cpp b/kite/src/RoutingPlane.cpp index 9dcf8a6e..5b3a08c1 100644 --- a/kite/src/RoutingPlane.cpp +++ b/kite/src/RoutingPlane.cpp @@ -160,7 +160,7 @@ namespace Kite { bool coherency = true; for ( size_t i=0 ; i<_tracks.size() ; i++ ) { - coherency = _tracks[i]->_check(overlaps) && coherency; + coherency = _tracks[i]->_check(overlaps) and coherency; } return coherency; diff --git a/kite/src/Track.cpp b/kite/src/Track.cpp index 2a040b1e..21c6e870 100644 --- a/kite/src/Track.cpp +++ b/kite/src/Track.cpp @@ -286,7 +286,7 @@ namespace Kite { TrackCost Track::getOverlapCost ( Interval interval, Net* net, size_t begin, size_t end ) const { - TrackCost cost ( const_cast(this), interval, begin, end ); + TrackCost cost ( const_cast(this), interval, begin, end, net ); ltrace(190) << "getOverlapCost() @" << DbU::getValueString(_axis) << " [" << DbU::getValueString(interval.getVMin()) @@ -538,7 +538,7 @@ namespace Kite { coherency = false; } - coherency = coherency && _segments[i]->_check (); + coherency = _segments[i]->_check () and coherency; } else { cerr << "[CHECK] Hole at position " << i << "." << endl; holes = true; @@ -547,7 +547,7 @@ namespace Kite { } if ( !holes ) - coherency = coherency && (checkOverlap(overlaps) == 0); + coherency = (checkOverlap(overlaps) == 0) and coherency; return coherency; } diff --git a/kite/src/TrackCost.cpp b/kite/src/TrackCost.cpp index d4aea624..fe448fb4 100644 --- a/kite/src/TrackCost.cpp +++ b/kite/src/TrackCost.cpp @@ -51,6 +51,7 @@ namespace Kite { , const Interval& interval , size_t begin , size_t end + , Net* net ) : _track (track) , _begin (begin) @@ -63,29 +64,41 @@ namespace Kite { , _overlap (false) , _leftOverlap (false) , _rightOverlap (false) + , _overlapGlobal (false) , _terminals (0) , _delta (-interval.getSize()) , _deltaShared (0) , _deltaPerpand (0) , _axisWeight (0) - , _distanceToFixed(DbU::Max) + , _distanceToFixed(DbU::lambda(100.0)) , _dataState (0) , _ripupCount (0) { TrackElement* neighbor; if ( _begin != Track::NPOS ) { neighbor = _track->getSegment(_begin); - if ( neighbor && neighbor->isFixed() ) { - if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0; - _distanceToFixed += interval.getVMin() - neighbor->getTargetU(); + if ( neighbor and (neighbor->getNet() != net) ) { + DbU::Unit distance = interval.getVMin() - neighbor->getTargetU(); + if ( distance < DbU::lambda(50.0) ) + _distanceToFixed = distance; } + // if ( neighbor and neighbor->isFixed() ) { + // if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0; + // _distanceToFixed += interval.getVMin() - neighbor->getTargetU(); + // } } if ( _end != Track::NPOS ) { neighbor = _track->getSegment(_end); - if ( neighbor && neighbor->isFixed() ) { - if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0; - _distanceToFixed += neighbor->getSourceU() - interval.getVMax(); + if ( neighbor and (neighbor->getNet() != net) ) { + DbU::Unit distance = neighbor->getSourceU() - interval.getVMax(); + if ( _distanceToFixed == DbU::lambda(100.0) ) _distanceToFixed = 0; + if ( distance < DbU::lambda(50.0) ) + _distanceToFixed += distance; } + // if ( neighbor and neighbor->isFixed() ) { + // if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0; + // _distanceToFixed += neighbor->getSourceU() - interval.getVMax(); + // } } } @@ -100,36 +113,36 @@ namespace Kite { } - bool operator< ( const TrackCost& lhs, const TrackCost& rhs ) + bool TrackCost::Compare::operator() ( const TrackCost& lhs, const TrackCost& rhs ) { if ( lhs._infinite xor rhs._infinite ) return rhs._infinite; + + if ( (_flags & TrackCost::DiscardGlobals) + and (lhs._overlapGlobal xor rhs._overlapGlobal) ) + return rhs._overlapGlobal; + if ( lhs._hardOverlap xor rhs._hardOverlap ) return rhs._hardOverlap; - int lhsRipupCost = (lhs._dataState<<2) + lhs._ripupCount; - int rhsRipupCost = (rhs._dataState<<2) + rhs._ripupCount; + if ( lhs._ripupCount + (int)Session::getRipupCost() < rhs._ripupCount ) return true; + if ( lhs._ripupCount > (int)Session::getRipupCost() + rhs._ripupCount ) return false; - // if ( lhs._ripupCount + (int)Session::getRipupCost() < rhs._ripupCount ) return true; - // if ( lhs._ripupCount > rhs._ripupCount + (int)Session::getRipupCost() ) return false; - - if ( lhsRipupCost + (int)Session::getRipupCost() < rhsRipupCost ) return true; - if ( lhsRipupCost > (int)Session::getRipupCost() + rhsRipupCost ) return false; + //int lhsRipupCost = (lhs._dataState<<2) + lhs._ripupCount; + //int rhsRipupCost = (rhs._dataState<<2) + rhs._ripupCount; + //if ( lhsRipupCost + (int)Session::getRipupCost() < rhsRipupCost ) return true; + //if ( lhsRipupCost > (int)Session::getRipupCost() + rhsRipupCost ) return false; if ( lhs._overlap xor rhs._overlap ) return rhs._overlap; - //std::cerr << "lhs:" << lhs._ripupCount - // << " rhs:" << rhs._ripupCount - // << " " << rhs._ripupCount - lhs._ripupCount << " > " << Session::getRipupCost() - // << std::endl; - //if ( lhs._ripupCount - rhs._ripupCount > (int)Session::getRipupCost() ) return false; - 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 ( lhs._axisWeight < rhs._axisWeight ) return true; - if ( lhs._axisWeight > rhs._axisWeight ) return false; + if ( not (_flags & TrackCost::IgnoreAxisWeight) ) { + if ( lhs._axisWeight < rhs._axisWeight ) return true; + if ( lhs._axisWeight > rhs._axisWeight ) return false; + } if ( lhs._deltaPerpand < rhs._deltaPerpand ) return true; if ( lhs._deltaPerpand > rhs._deltaPerpand ) return false; @@ -161,10 +174,13 @@ namespace Kite { string s = "<" + _getTypeName(); s += " " + getString(_track); - s += " " + getString(_ripupCount); - s += " " + string ( (_blockage )?"b":"-" ); - s += string ( (_hardOverlap)?"h":"-" ); - s += string ( (_overlap )?"o":"-" ); + 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 += " " + getString(_terminals); s += "/" + DbU::getValueString(_delta); s += "/" + DbU::getValueString(_axisWeight); diff --git a/kite/src/TrackElement.cpp b/kite/src/TrackElement.cpp index cd0d404b..6bb60e21 100644 --- a/kite/src/TrackElement.cpp +++ b/kite/src/TrackElement.cpp @@ -162,7 +162,7 @@ namespace Kite { unsigned int TrackElement::getDogLegOrder () const { return 0; } Interval TrackElement::getSourceConstraints () const { return Interval(); } Interval TrackElement::getTargetConstraints () const { return Interval(); } - DataNegociate* TrackElement::getDataNegociate () const { return NULL; } + DataNegociate* TrackElement::getDataNegociate ( unsigned int ) const { return NULL; } TrackElements TrackElement::getCollapsedPerpandiculars () { return new TrackElements_CollapsedPerpandicular(NULL); } void TrackElement::setAllowOutsideGCell ( bool ) { } void TrackElement::setLock ( bool ) { } @@ -177,12 +177,14 @@ namespace Kite { bool TrackElement::canDesalignate () const { return false; } bool TrackElement::canPivotUp ( float ) const { return false; }; + bool TrackElement::canPivotDown ( float ) const { return false; }; bool TrackElement::canMoveUp ( float, unsigned int ) const { return false; }; bool TrackElement::canDogLeg () { return false; }; bool TrackElement::canDogLeg ( Interval ) { return false; }; - bool TrackElement::canDogLegAt ( Katabatic::GCell*, bool allowReuse ) { return false; }; + bool TrackElement::canDogLegAt ( Katabatic::GCell*, unsigned int ) { return false; }; TrackElement* TrackElement::getSourceDogLeg () { return NULL; } TrackElement* TrackElement::getTargetDogLeg () { return NULL; } + TrackElement* TrackElement::getParent () const { return NULL; } void TrackElement::dataInvalidate () { } void TrackElement::eventInvalidate () { } void TrackElement::setArea () { } @@ -197,6 +199,7 @@ namespace Kite { void TrackElement::setAxis ( DbU::Unit, unsigned int flags ) { } void TrackElement::slacken () { } bool TrackElement::moveUp ( unsigned int ) { return false; } + bool TrackElement::moveDown ( unsigned int ) { return false; } bool TrackElement::moveAside ( bool onLeft ) { return false; } TrackElement* TrackElement::makeDogLeg () { return NULL; } TrackElement* TrackElement::makeDogLeg ( Interval, bool& leftDogleg ) { return NULL; } diff --git a/kite/src/TrackFixedSegment.cpp b/kite/src/TrackFixedSegment.cpp index 56080c6c..789d4b8d 100644 --- a/kite/src/TrackFixedSegment.cpp +++ b/kite/src/TrackFixedSegment.cpp @@ -111,14 +111,14 @@ namespace Kite { guside = gcell->getUSide ( Constant::Horizontal /*, true*/ ); Interval usedLength = guside.getIntersection ( segside ); - gcell->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + gcell->addBlockage ( depth, usedLength.getSize() ); gcell = right; } if ( end ) { guside = gcell->getUSide ( Constant::Horizontal /*, true*/ ); Interval usedLength = guside.getIntersection ( segside ); - end->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + end->addBlockage ( depth, usedLength.getSize() ); } } else cerr << Warning("TrackFixedSegment(): TrackFixedElement outside GCell grid.") << endl; @@ -141,14 +141,14 @@ namespace Kite { guside = gcell->getUSide ( Constant::Vertical /*, true*/ ); Interval usedLength = guside.getIntersection ( segside ); - gcell->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + gcell->addBlockage ( depth, usedLength.getSize() ); gcell = up; } if ( end ) { guside = gcell->getUSide ( Constant::Vertical /*, true*/ ); Interval usedLength = guside.getIntersection ( segside ); - end->addBlockage ( depth, (float)usedLength.getSize()/(float)guside.getSize() ); + end->addBlockage ( depth, usedLength.getSize() ); } } else cerr << Warning("TrackFixedSegment(): TrackFixedElement outside GCell grid.") << endl; diff --git a/kite/src/TrackSegment.cpp b/kite/src/TrackSegment.cpp index 154b0a6f..fe6b238f 100644 --- a/kite/src/TrackSegment.cpp +++ b/kite/src/TrackSegment.cpp @@ -38,7 +38,6 @@ #include "crlcore/RoutingGauge.h" #include "kite/DataNegociate.h" #include "kite/TrackSegment.h" -#include "kite/TrackCost.h" #include "kite/Track.h" #include "kite/Session.h" #include "kite/RoutingEvent.h" @@ -157,7 +156,6 @@ namespace Kite { unsigned int TrackSegment::getDogLegLevel () const { return _dogLegLevel; } Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); } Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); } - DataNegociate* TrackSegment::getDataNegociate () const { return _data; } TrackElements TrackSegment::getCollapsedPerpandiculars () { return new TrackElements_CollapsedPerpandicular(this); } void TrackSegment::setAllowOutsideGCell ( bool state ) { _base->setAllowOutsideGCell(state,true); } void TrackSegment::setLock ( bool state ) { _lock = state; } @@ -196,12 +194,13 @@ namespace Kite { { return _base->getLayer(); } - // DbU::Unit TrackSegment::getSourceU () const - // { return _base->getSourceU(); } + DataNegociate* TrackSegment::getDataNegociate ( unsigned int flags ) const + { + if ( flags & TrackElement::DataSelf ) return _data; - - // DbU::Unit TrackSegment::getTargetU () const - // { return _base->getTargetU(); } + TrackElement* parent = getParent(); + return (parent) ? parent->getDataNegociate() : NULL; + } TrackElement* TrackSegment::getNext () const @@ -218,6 +217,16 @@ namespace Kite { } + TrackElement* TrackSegment::getParent () const + { + AutoSegment* baseParent = base()->getParent(); + if ( not baseParent ) return NULL; + + TrackElement* element = Session::lookup ( baseParent ); + return element; + } + + Interval TrackSegment::getFreeInterval () const { if ( not _track ) return Interval(false); @@ -412,7 +421,7 @@ namespace Kite { other->getTrack()->_check(); #endif - RoutingEvent* thisEvent = getDataNegociate()->getRoutingEvent(); + RoutingEvent* thisEvent = getDataNegociate(TrackElement::DataSelf)->getRoutingEvent(); RoutingEvent* otherEvent = other->getDataNegociate()->getRoutingEvent(); if ( thisEvent ) thisEvent ->setSegment ( other ); @@ -459,6 +468,10 @@ namespace Kite { { return _base->canPivotUp(reserve); } + bool TrackSegment::canPivotDown ( float reserve ) const + { return _base->canPivotDown(reserve); } + + bool TrackSegment::canMoveUp ( float reserve, unsigned int flags ) const { return _base->canMoveUp ( reserve, flags ); } @@ -478,7 +491,7 @@ namespace Kite { for ( size_t i=0 ; iaddTrackSegment(invalidateds[i],false); if ( segment != NULL ) { - ltrace(200) << "moved: " << invalidateds[i] << endl; + ltrace(200) << "moved up: " << invalidateds[i] << endl; segments.push_back ( segment ); // if ( (segment->getTrack() == NULL) // or (segment->getLayer() != segment->getTrack()->getLayer()) ) @@ -486,7 +499,45 @@ namespace Kite { } } for ( size_t i=0 ; isetState ( DataNegociate::ConflictSolve1, true ); + // _data->resetRipupCount (); + // } + + ltraceout(200); + + return success; + } + + + bool TrackSegment::moveDown ( unsigned int flags ) + { + bool success = false; + + ltrace(200) << "TrackSegment::moveDown() " << flags << endl; + ltracein(200); + + success = base()->moveDown ( flags ); + + const vector& invalidateds = Session::getInvalidateds(); + if ( not invalidateds.empty() ) { + vector segments; + for ( size_t i=0 ; iaddTrackSegment(invalidateds[i],false); + if ( segment != NULL ) { + ltrace(200) << "moved down: " << invalidateds[i] << endl; + segments.push_back ( segment ); + // if ( (segment->getTrack() == NULL) + // or (segment->getLayer() != segment->getTrack()->getLayer()) ) + segment->reschedule ( 0 ); + } + } + for ( size_t i=0 ; iisCanonical() ) { + if ( not base()->isCanonical() ) { cerr << "[CHECK] " << this << " supporting AutoSegment is not canonical." << endl; coherency = false; } diff --git a/kite/src/kite/DataNegociate.h b/kite/src/kite/DataNegociate.h index 6b353539..8305960a 100644 --- a/kite/src/kite/DataNegociate.h +++ b/kite/src/kite/DataNegociate.h @@ -64,9 +64,9 @@ namespace Kite { public: enum SlackState { RipupPerpandiculars= 1 - , Minimize = 2 - , DogLeg = 3 - , Desalignate = 4 + , Desalignate = 2 + , Minimize = 3 + , DogLeg = 4 , Slacken = 5 , ConflictSolve1 = 6 , ConflictSolve2 = 7 diff --git a/kite/src/kite/NegociateWindow.h b/kite/src/kite/NegociateWindow.h index 7da3b6a8..372f7db4 100644 --- a/kite/src/kite/NegociateWindow.h +++ b/kite/src/kite/NegociateWindow.h @@ -37,6 +37,7 @@ namespace Hurricane { #include "katabatic/Grid.h" #include "kite/RoutingEventQueue.h" #include "kite/RoutingEventHistory.h" +#include "kite/RoutingEventLoop.h" namespace Kite { @@ -114,6 +115,7 @@ namespace Kite { inline const Katabatic::GCellVector& getGCells () const; inline RoutingEventQueue& getEventQueue (); inline RoutingEventHistory& getEventHistory (); + inline RoutingEventLoop& getEventLoop (); inline Stage getStage () const; void setGCells ( const Katabatic::GCellVector& ); inline void setInterrupt ( bool ); @@ -139,6 +141,7 @@ namespace Kite { std::vector _segments; RoutingEventQueue _eventQueue; RoutingEventHistory _eventHistory; + RoutingEventLoop _eventLoop; Statistics _statistics; // Constructors. diff --git a/kite/src/kite/RoutingEvent.h b/kite/src/kite/RoutingEvent.h index d5986e85..11f55456 100644 --- a/kite/src/kite/RoutingEvent.h +++ b/kite/src/kite/RoutingEvent.h @@ -27,6 +27,7 @@ #define __KITE_ROUTING_EVENT__ #include +#include #include "hurricane/Interval.h" namespace Hurricane { @@ -48,6 +49,7 @@ namespace Kite { class Track; class RoutingEventHistory; class RoutingEventQueue; + class RoutingEventLoop; // ------------------------------------------------------------------- @@ -91,66 +93,72 @@ namespace Kite { enum Mode { Negociate=1, Pack=2, PostPack=3 }; public: - static size_t getAllocateds (); - static size_t getProcesseds (); - static size_t getCloneds (); - static void resetProcesseds (); - public: - static RoutingEvent* create ( TrackElement*, unsigned int mode=Negociate ); - RoutingEvent* clone () const; - void destroy (); - inline bool isCloned () const; - inline bool isValid () const; - bool isUnimplemented () const; - inline bool isProcessed () const; - inline bool isDisabled () const; - inline bool isForcedToHint () const; - inline bool isSheared () const; - inline bool getMode () const; - inline bool canMinimize () const; - unsigned int getState () const; - inline const Key& getKey () const; - inline TrackElement* getSegment () const; - inline const vector& getPerpandiculars () const; - inline DbU::Unit getAxisHint () const; - inline DbU::Unit getAxisHistory () const; - long getAxisWeight ( DbU::Unit ) const; - inline const Interval& getOptimalAxis () const; - inline const Interval& getConstraints () const; - inline const Interval& getOptimal () const; - inline const Interval& getPerpandicular () const; - inline Katabatic::GCell* getShearGCell () const; - inline float getPriority () const; - inline unsigned int getTracksNb () const; - inline unsigned int getTracksFree () const; - inline unsigned int getInsertState () const; - inline unsigned int getEventLevel () const; - inline void invalidate ( bool withPerpandiculars=false, bool withConstraints=false ); - void revalidate ( bool force=false ); - inline void updateKey (); - void process ( RoutingEventQueue&, RoutingEventHistory& ); - void setSegment ( TrackElement* ); - RoutingEvent* reschedule ( RoutingEventQueue&, unsigned int eventLevel ); - inline void setMode ( unsigned int ); - void setState ( unsigned int ); - inline void setProcessed ( bool state=true ); - inline void setDisabled ( bool state=true ); - inline void setMinimized ( bool state=true ); - void setEventLevel ( unsigned int ); - inline void setTracksFree ( unsigned int ); - inline void setForcedToHint ( bool state = true ); - void setAxisHint ( DbU::Unit ); - inline void setOptimalAxis ( Interval ); - inline void incInsertState (); - inline void resetInsertState (); - void _processNegociate ( RoutingEventQueue&, RoutingEventHistory& ); - void _processPacking ( RoutingEventQueue&, RoutingEventHistory& ); - Record* _getRecord () const; - string _getString () const; - string _getTypeName () const; - private: - RoutingEvent ( TrackElement*, unsigned int mode ); - ~RoutingEvent (); + static size_t getAllocateds (); + static size_t getProcesseds (); + static size_t getCloneds (); + static void resetProcesseds (); + public: + static RoutingEvent* create ( TrackElement*, unsigned int mode=Negociate ); + RoutingEvent* clone () const; + void destroy (); + inline bool isCloned () const; + inline bool isValid () const; + bool isUnimplemented () const; + inline bool isProcessed () const; + inline bool isDisabled () const; + inline bool isForcedToHint () const; + inline bool isSheared () const; + inline bool isRipedByLocal () const; + inline bool getMode () const; + inline bool canMinimize () const; + unsigned int getState () const; + inline const Key& getKey () const; + inline TrackElement* getSegment () const; + inline const vector& getPerpandiculars () const; + inline DbU::Unit getAxisHint () const; + inline DbU::Unit getAxisHistory () const; + inline long getAxisWeight ( DbU::Unit ) const; + inline const Interval& getOptimalAxis () const; + inline const Interval& getConstraints () const; + inline const Interval& getOptimal () const; + inline const Interval& getPerpandicular () const; + inline Katabatic::GCell* getShearGCell () const; + inline float getPriority () const; + inline unsigned int getTracksNb () const; + inline unsigned int getTracksFree () const; + inline unsigned int getInsertState () const; + inline unsigned int getEventLevel () const; + inline void invalidate ( bool withPerpandiculars=false, bool withConstraints=false ); + void revalidate ( bool force=false ); + inline void updateKey (); + void process ( RoutingEventQueue& + , RoutingEventHistory& + , RoutingEventLoop& + ); + void setSegment ( TrackElement* ); + RoutingEvent* reschedule ( RoutingEventQueue&, unsigned int eventLevel ); + inline void setMode ( unsigned int ); + void setState ( unsigned int ); + inline void setProcessed ( bool state=true ); + inline void setDisabled ( bool state=true ); + inline void setMinimized ( bool state=true ); + inline void setRipedByLocal ( bool state=true ); + void setEventLevel ( unsigned int ); + inline void setTracksFree ( unsigned int ); + inline void setForcedToHint ( bool state = true ); + void setAxisHint ( DbU::Unit ); + void cacheAxisHint (); + inline void setOptimalAxis ( Interval ); + inline void incInsertState (); + inline void resetInsertState (); + void _processNegociate ( RoutingEventQueue&, RoutingEventHistory& ); + void _processPacking ( RoutingEventQueue&, RoutingEventHistory& ); + Record* _getRecord () const; + string _getString () const; + string _getTypeName () const; + private: + RoutingEvent ( TrackElement*, unsigned int mode ); + ~RoutingEvent (); protected: // Attributes. @@ -166,6 +174,7 @@ namespace Kite { bool _canHandleConstraints; bool _minimized; bool _forceToHint; + bool _ripedByLocal; TrackElement* _segment; DbU::Unit _axisHistory; DbU::Unit _axisHint; @@ -193,13 +202,15 @@ namespace Kite { inline bool RoutingEvent::isDisabled () const { return _disabled; } inline bool RoutingEvent::isForcedToHint () const { return _forceToHint; } inline bool RoutingEvent::isSheared () const { return (_shearGCell != NULL); } + inline bool RoutingEvent::isRipedByLocal () const { return _ripedByLocal; } inline bool RoutingEvent::getMode () const { return _mode; } inline bool RoutingEvent::canMinimize () const { return !_minimized; } inline const RoutingEvent::Key& RoutingEvent::getKey () const { return _key; } inline TrackElement* RoutingEvent::getSegment () const { return _segment; } inline const vector& RoutingEvent::getPerpandiculars () const { return _perpandiculars; } - inline DbU::Unit RoutingEvent::getAxisHint () const { return _axisHint; } inline DbU::Unit RoutingEvent::getAxisHistory () const { return _axisHistory; } + inline DbU::Unit RoutingEvent::getAxisHint () const { return _axisHint; } + inline long RoutingEvent::getAxisWeight ( DbU::Unit axis ) const { return abs(axis - getAxisHint()); } inline const Interval& RoutingEvent::getOptimalAxis () const { return _optimalAxis; } inline const Interval& RoutingEvent::getConstraints () const { return _constraints; } inline const Interval& RoutingEvent::getOptimal () const { return _optimal; } @@ -214,6 +225,7 @@ namespace Kite { inline void RoutingEvent::setProcessed ( bool state ) { _processed = state; } inline void RoutingEvent::setDisabled ( bool state ) { _disabled = state; } inline void RoutingEvent::setMinimized ( bool state ) { _minimized = state; } + inline void RoutingEvent::setRipedByLocal ( bool state ) { _ripedByLocal = state; } inline void RoutingEvent::setTracksFree ( unsigned int nb ) { _tracksFree = nb; } inline void RoutingEvent::setForcedToHint ( bool state ) { _forceToHint = state; } inline void RoutingEvent::setOptimalAxis ( Interval i ) { _optimalAxis = i; } diff --git a/kite/src/kite/RoutingEventHistory.h b/kite/src/kite/RoutingEventHistory.h index eebadad7..72528b75 100644 --- a/kite/src/kite/RoutingEventHistory.h +++ b/kite/src/kite/RoutingEventHistory.h @@ -49,7 +49,6 @@ namespace Kite { public: RoutingEventHistory (); ~RoutingEventHistory (); - inline bool looping () const; inline bool empty () const; inline size_t size () const; RoutingEvent* getNth ( size_t ) const; @@ -64,7 +63,6 @@ namespace Kite { protected: // Attributes. vector _events; - size_t _identicals; private: RoutingEventHistory& operator= ( const RoutingEventHistory& ); @@ -74,7 +72,6 @@ namespace Kite { // Inline Functions. - inline bool RoutingEventHistory::looping () const { return _identicals > 30; } inline bool RoutingEventHistory::empty () const { return _events.empty(); } inline size_t RoutingEventHistory::size () const { return _events.size(); } inline string RoutingEventHistory::_getTypeName () const { return "RoutingEventHistory"; } diff --git a/kite/src/kite/RoutingEventLoop.h b/kite/src/kite/RoutingEventLoop.h new file mode 100644 index 00000000..3c64f9ec --- /dev/null +++ b/kite/src/kite/RoutingEventLoop.h @@ -0,0 +1,93 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2008-2010, 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 | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./kite/RoutingEventLoop.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __KITE_ROUTING_EVENT_LOOP__ +#define __KITE_ROUTING_EVENT_LOOP__ + +#include + + +namespace Kite { + + class RoutingEvent; + + +// ------------------------------------------------------------------- +// Class : "RoutingEventLoop". + + + class RoutingEventLoop { + public: + class Element { + public: + inline Element ( size_t id=0, size_t timestamp=0 ); + public: + size_t _id; + size_t _timestamp; + int _count; + }; + class CompareByTimestamp { + public: + inline bool operator() ( const Element& lhs, const Element& rhs ); + }; + public: + RoutingEventLoop ( size_t depth=10, int limit=20 ); + inline bool isLooping () const; + inline int getMaxCount () const; + inline const std::vector& getElements () const; + void update ( size_t id ); + void erase ( size_t id ); + private: + std::vector _elements; + size_t _depth; + int _maxCount; + int _countLimit; + bool _isLooping; + }; + + + inline RoutingEventLoop::Element::Element ( size_t id, size_t timestamp ) + : _id(id), _timestamp(timestamp), _count(1) + { } + + + inline bool RoutingEventLoop::CompareByTimestamp::operator() ( const RoutingEventLoop::Element& lhs, const RoutingEventLoop::Element& rhs ) + { return lhs._timestamp > rhs._timestamp; } + + + inline bool RoutingEventLoop::isLooping () const { return _isLooping; } + inline int RoutingEventLoop::getMaxCount () const { return _maxCount; } + inline const std::vector& + RoutingEventLoop::getElements () const { return _elements; } + + + +} // End of Kite namespace. + + +//INSPECTOR_P_SUPPORT(Kite::RoutingEvent); + + +#endif // __KITE_ROUTING_EVENT_LOOP__ diff --git a/kite/src/kite/TrackCost.h b/kite/src/kite/TrackCost.h index d6c3b74e..9a020046 100644 --- a/kite/src/kite/TrackCost.h +++ b/kite/src/kite/TrackCost.h @@ -30,6 +30,9 @@ #include #include "hurricane/Interval.h" +namespace Hurricane { + class Net; +} namespace Kite { @@ -39,6 +42,7 @@ namespace Kite { using Hurricane::Record; using Hurricane::DbU; using Hurricane::Interval; + using Hurricane::Net; class Track; @@ -46,6 +50,8 @@ namespace Kite { // Class : "TrackCost". class TrackCost { + public: + enum Flags { IgnoreAxisWeight=0x1, DiscardGlobals=0x2 }; public: // Sub-Class: "CompareByDelta()". @@ -53,52 +59,61 @@ namespace Kite { public: bool operator() ( const TrackCost& lhs, const TrackCost& rhs ); }; + class Compare { + public: + inline Compare ( unsigned int flags=0 ); + bool operator() ( const TrackCost& lhs, const TrackCost& rhs ); + private: + unsigned int _flags; + }; public: - TrackCost ( Track* track - , const Interval& interval - , size_t begin - , size_t end - ); - ~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; - 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 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 + ); + ~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; // Operators. - friend bool operator< ( const TrackCost& lhs, const TrackCost& rhs ); // Attributes. protected: @@ -113,6 +128,7 @@ namespace Kite { bool _overlap; bool _leftOverlap; bool _rightOverlap; + bool _overlapGlobal; unsigned int _terminals; DbU::Unit _delta; DbU::Unit _deltaShared; @@ -133,6 +149,7 @@ namespace Kite { 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; } @@ -149,6 +166,7 @@ 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::incTerminals ( unsigned int terminals ) { _terminals += terminals; } inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } @@ -158,6 +176,8 @@ namespace Kite { 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) { } + } // End of Kite namespace. diff --git a/kite/src/kite/TrackElement.h b/kite/src/kite/TrackElement.h index fb344582..0b9e5d60 100644 --- a/kite/src/kite/TrackElement.h +++ b/kite/src/kite/TrackElement.h @@ -74,7 +74,14 @@ namespace Kite { class TrackElement { public: - enum Flags { AddToGCells=0x1, RemoveFromGCells=0x2, UnRouted=0x4, Routed=0x8 }; + enum Flags { AddToGCells =0x01 + , RemoveFromGCells=0x02 + , UnRouted =0x04 + , Routed =0x08 + , AllowDoglegReuse=0x10 + , DataSelf =0x01 + , DataParent =0x02 + }; public: // Sub-Class: "Compare()". @@ -116,13 +123,14 @@ namespace Kite { virtual bool canGoOutsideGCell () const; virtual bool canSlacken () const; virtual bool canPivotUp ( float reserve ) const; - virtual bool canMoveUp ( float reserve, unsigned int flags=/*Katabatic::AutoSegment::Propagate*/0 ) const; + virtual bool canPivotDown ( float reserve ) const; + virtual bool canMoveUp ( float reserve, unsigned int flags=AutoSegment::Propagate ) const; virtual bool canRipple () const; virtual bool hasSourceDogLeg () const; virtual bool hasTargetDogLeg () const; virtual bool canDogLeg (); virtual bool canDogLeg ( Interval ); - virtual bool canDogLegAt ( Katabatic::GCell*, bool allowReuse=false ); + virtual bool canDogLegAt ( Katabatic::GCell*, unsigned int flags=0 ); virtual unsigned long getId () const; virtual unsigned int getDirection () const = 0; virtual Net* getNet () const = 0; @@ -135,6 +143,7 @@ namespace Kite { virtual unsigned int getDogLegOrder () const; virtual TrackElement* getNext () const; virtual TrackElement* getPrevious () const; + virtual TrackElement* getParent () const; virtual DbU::Unit getAxis () const = 0; inline DbU::Unit getSourceU () const; inline DbU::Unit getTargetU () const; @@ -143,7 +152,7 @@ namespace Kite { inline Interval getCanonicalInterval () const; virtual Interval getSourceConstraints () const; virtual Interval getTargetConstraints () const; - virtual DataNegociate* getDataNegociate () const; + virtual DataNegociate* getDataNegociate ( unsigned int flags=DataSelf ) const; virtual TrackElement* getCanonical ( Interval& ); virtual size_t getGCells ( Katabatic::GCellVector& ) const; virtual TrackElement* getSourceDogLeg (); @@ -174,7 +183,8 @@ namespace Kite { virtual void invalidate (); virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet ); virtual void slacken (); - virtual bool moveUp ( unsigned int flags=/*Katabatic::AutoSegment::Propagate*/0 ); + virtual bool moveUp ( unsigned int flags=AutoSegment::Propagate ); + virtual bool moveDown ( unsigned int flags=AutoSegment::Propagate ); virtual bool moveAside ( bool onLeft ); virtual TrackElement* makeDogLeg (); virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg ); diff --git a/kite/src/kite/TrackSegment.h b/kite/src/kite/TrackSegment.h index 5a65b8e5..f422fa8d 100644 --- a/kite/src/kite/TrackSegment.h +++ b/kite/src/kite/TrackSegment.h @@ -78,13 +78,14 @@ namespace Kite { virtual bool canGoOutsideGCell () const; virtual bool canSlacken () const; virtual bool canPivotUp ( float reserve ) const; - virtual bool canMoveUp ( float reserve, unsigned int flags=Katabatic::AutoSegment::Propagate ) const; + virtual bool canPivotDown ( float reserve ) const; + virtual bool canMoveUp ( float reserve, unsigned int flags ) const; virtual bool canRipple () const; virtual bool hasSourceDogLeg () const; virtual bool hasTargetDogLeg () const; virtual bool canDogLeg (); virtual bool canDogLeg ( Interval ); - virtual bool canDogLegAt ( Katabatic::GCell*, bool allowReuse=false ); + virtual bool canDogLegAt ( Katabatic::GCell*, unsigned int flags ); virtual unsigned long getId () const; virtual unsigned int getDirection () const; virtual Net* getNet () const; @@ -93,11 +94,12 @@ namespace Kite { virtual unsigned int getDogLegLevel () const; virtual TrackElement* getNext () const; virtual TrackElement* getPrevious () const; + virtual TrackElement* getParent () const; virtual DbU::Unit getAxis () const; virtual Interval getFreeInterval () const; virtual Interval getSourceConstraints () const; virtual Interval getTargetConstraints () const; - virtual DataNegociate* getDataNegociate () const; + virtual DataNegociate* getDataNegociate ( unsigned int flags ) const; virtual TrackElement* getCanonical ( Interval& ); virtual size_t getGCells ( vector& ) const; virtual TrackElement* getSourceDogLeg (); @@ -109,8 +111,8 @@ namespace Kite { virtual void setAllowOutsideGCell ( bool ); virtual void setRevalidated ( bool ); virtual void setCanRipple ( bool ); - virtual void setSourceDogLeg ( bool state=true ); - virtual void setTargetDogLeg ( bool state=true ); + virtual void setSourceDogLeg ( bool ); + virtual void setTargetDogLeg ( bool ); virtual void setLock ( bool ); virtual void setRouted ( bool ); virtual void setTrack ( Track* ); @@ -119,11 +121,12 @@ namespace Kite { virtual void swapTrack ( TrackElement* ); virtual void reschedule ( unsigned int level ); virtual void detach (); - virtual void revalidate ( bool invalidEvent=false ); + virtual void revalidate ( bool invalidEvent ); virtual void invalidate (); - virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet ); + virtual void setAxis ( DbU::Unit, unsigned int flags ); virtual void slacken (); - virtual bool moveUp ( unsigned int flags=Katabatic::AutoSegment::Propagate ); + virtual bool moveUp ( unsigned int flags ); + virtual bool moveDown ( unsigned int flags ); virtual bool moveAside ( bool onLeft ); virtual TrackElement* makeDogLeg (); virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg );