From ef69a6d58680f4b50e71d6d5b3b402e5a485a87e Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 30 Apr 2017 23:46:33 +0200 Subject: [PATCH 1/4] Support for symmetric routing in Anabatic/Katabatic. * New: In Katana::SegmentFsm, the object is now able to handle two events at the same time. The master and it's symmetric. When there is no symmetric, the corresponing data is just left blank. This makes a bigger object, but as there is only one when running, it is not an issue. Candidates tracks are now an vector of array<2> (pairs), the TrackCost::Compare() functor has to be wrapped through CompareCostArray. The compined TrackCost of the two tracks is accumulated into the first element. Everything related to events gets duplicated: _event is now _event1 and _event2, and so on. As there can be now two Manipulator actions done with SegmentFsm, this class now completly hide the Manipulator level from the RoutingEvent processing. New function ::bindToTrack() to perform the track insertion. * New: In Katana::TrackCost, add a new ::merge() function. * New: In Katana::TrackElement and Katana::TrackSegment, add symmetric management. Allows to know if a TrackElement has a symmetric and to access it. * New: In Katana::DataSymmetric, add new overload for ::getSymmetrical() to handle DbU::Unit and intervals. * Change: In Katana::RoutingEvent, remove all direct uses of Manipulator objects. Now any change to the event associated segment must go through call to Segment Fsm. * Change: In Katana, adjust the debug level so internal informations are put below level 156. * New: In Hurricane::DbU, in ::getValueString(), special display when the value is Min or Max (more helpful than a gigantic number). --- anabatic/src/AutoSegment.cpp | 46 ++-- hurricane/src/hurricane/DbU.cpp | 7 +- katana/src/DataNegociate.cpp | 2 +- katana/src/DataSymmetric.cpp | 17 +- katana/src/GraphicKatanaEngine.cpp | 5 +- katana/src/Manipulator.cpp | 36 +-- katana/src/RoutingEvent.cpp | 43 ++-- katana/src/SegmentFsm.cpp | 342 +++++++++++++++++++++------- katana/src/SymmetricRoute.cpp | 43 +++- katana/src/TrackCost.cpp | 15 +- katana/src/TrackElement.cpp | 3 + katana/src/TrackSegment.cpp | 24 +- katana/src/TrackSegmentCost.cpp | 2 +- katana/src/Tracks.cpp | 30 +-- katana/src/katana/DataSymmetric.h | 60 +++-- katana/src/katana/KatanaEngine.h | 4 + katana/src/katana/NegociateWindow.h | 51 +++-- katana/src/katana/RoutingEvent.h | 8 +- katana/src/katana/SegmentFsm.h | 174 ++++++++------ katana/src/katana/TrackCost.h | 7 +- katana/src/katana/TrackElement.h | 3 + katana/src/katana/TrackSegment.h | 4 + 22 files changed, 622 insertions(+), 304 deletions(-) diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index be78df56..1dc88802 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -822,7 +822,7 @@ namespace Anabatic { DbU::Unit optimalMax = min( max(getOptimalMax(),constraintMin), constraintMax ); cdebug_log(149,0) << "optimal:[" << DbU::getValueString(optimalMin) - << " " << DbU::getValueString(optimalMin) << "]" << endl; + << " " << DbU::getValueString(optimalMax) << "]" << endl; if (getAxis() < optimalMin) { setAxis( optimalMin, flags ); @@ -973,30 +973,30 @@ namespace Anabatic { if (perpandMin < minGCell) attractors.addAttractor( minGCell ); if (perpandMax > maxGCell) attractors.addAttractor( maxGCell ); - } else if (autoSegment->isLongLocal()) { - cdebug_log(145,0) << "| Used as long global attractor." << endl; - - DbU::Unit perpandMin = autoSegment->getSourceU(); - DbU::Unit perpandMax = autoSegment->getTargetU(); - - if (perpandMin != perpandMax) { - if (perpandMin == getAxis()) attractors.addAttractor( perpandMax ); - if (perpandMax == getAxis()) attractors.addAttractor( perpandMin ); - } } else if (autoSegment->isLocal()) { - if (not autoSegment->isStrongTerminal()) { cdebug_tabw(145,-1); continue; } + if (autoSegment->isStrongTerminal()) { + DbU::Unit terminalMin; + DbU::Unit terminalMax; - DbU::Unit terminalMin; - DbU::Unit terminalMax; - - if (getTerminalInterval( *autoSegment - , NULL - , isHorizontal() - , terminalMin - , terminalMax )) { - attractors.addAttractor( terminalMin ); - if (terminalMin != terminalMax) - attractors.addAttractor( terminalMax ); + if (getTerminalInterval( *autoSegment + , NULL + , isHorizontal() + , terminalMin + , terminalMax )) { + attractors.addAttractor( terminalMin ); + if (terminalMin != terminalMax) + attractors.addAttractor( terminalMax ); + } + } else if (autoSegment->isLongLocal()) { + cdebug_log(145,0) << "| Used as long global attractor." << endl; + + DbU::Unit perpandMin = autoSegment->getSourceU(); + DbU::Unit perpandMax = autoSegment->getTargetU(); + + if (perpandMin != perpandMax) { + if (perpandMin == getAxis()) attractors.addAttractor( perpandMax ); + if (perpandMax == getAxis()) attractors.addAttractor( perpandMin ); + } } } cdebug_tabw(145,-1); diff --git a/hurricane/src/hurricane/DbU.cpp b/hurricane/src/hurricane/DbU.cpp index 319b8954..56725241 100644 --- a/hurricane/src/hurricane/DbU.cpp +++ b/hurricane/src/hurricane/DbU.cpp @@ -323,7 +323,12 @@ namespace Hurricane { case Kilo: unitPower = 'k'; break; default: unitPower = '?'; break; } - os << setprecision(3) << toPhysical(u,_stringModeUnitPower); + switch ( u ) { + case Min: os << "MIN:"; break; + case Max: os << "MAX:"; break; + default: + os << setprecision(3) << toPhysical(u,_stringModeUnitPower); + } } else { if (_stringMode != Db) cerr << "[ERROR] Unknown Unit representation mode: " << _stringMode << endl; diff --git a/katana/src/DataNegociate.cpp b/katana/src/DataNegociate.cpp index 0014e90d..ead77203 100644 --- a/katana/src/DataNegociate.cpp +++ b/katana/src/DataNegociate.cpp @@ -79,7 +79,7 @@ namespace Katana { void DataNegociate::update () { - DebugSession::open( _trackSegment->getNet(), 150, 160 ); + DebugSession::open( _trackSegment->getNet(), 156, 160 ); //cdebug_log(9000,0) << "Deter| DataNegociate::update() - " << _trackSegment << endl; cdebug_log(159,1) << "DataNegociate::update() - " << _trackSegment << endl; diff --git a/katana/src/DataSymmetric.cpp b/katana/src/DataSymmetric.cpp index f0b44a6c..cab79906 100644 --- a/katana/src/DataSymmetric.cpp +++ b/katana/src/DataSymmetric.cpp @@ -15,6 +15,7 @@ #include "anabatic/AutoSegment.h" #include "katana/DataSymmetric.h" +#include "katana/Session.h" namespace { @@ -124,6 +125,10 @@ namespace Katana { const unsigned int mask = ~(AutoSegmentFlag::SegIsReduced); Message errors ( 0, "[ERROR]" ); + // Temporary hardwired: M2 (depth 1) for H pitch, M3 (depth 2) for V pitch. + DbU::Unit hPitch = Session::getPitch( 1 ); + DbU::Unit vPitch = Session::getPitch( 2 ); + size_t refs = 0; size_t syms = 0; for ( const array& paired : _paireds ) { @@ -162,7 +167,7 @@ namespace Katana { _valid = false; } - if (2*getSymAxis() - paired[0]->getAxis() != paired[1]->getAxis()) { + if (std::abs( 2*getSymAxis() - paired[0]->getAxis() - paired[1]->getAxis() ) > 2*vPitch ) { errors.newline() << "Mirror axis mismatch @ [" << index << "] " << DbU::getValueString(paired[1]->getAxis()) << " (should be: " << DbU::getValueString(2*getSymAxis() - paired[0]->getAxis()) << ")"; @@ -179,7 +184,7 @@ namespace Katana { _valid = false; } - if (paired[0]->getAxis() != paired[1]->getAxis()) { + if ( std::abs( paired[0]->getAxis() - paired[1]->getAxis() ) > 2*hPitch ) { errors.newline() << "Axis mismatch index " << index << " " << DbU::getValueString(paired[1]->getAxis()) << " (should be:" << DbU::getValueString(paired[0]->getAxis()) << ")"; @@ -190,7 +195,7 @@ namespace Katana { } } else { if (paired[0]->isHorizontal()) { - if (2*getSymAxis() - paired[0]->getAxis() != paired[1]->getAxis()) { + if ( std::abs( 2*getSymAxis() - paired[0]->getAxis() - paired[1]->getAxis() ) > 2*hPitch ) { errors.newline() << "Mirror axis mismatch index " << index << " " << DbU::getValueString(paired[1]->getAxis()) << " (should be:" << DbU::getValueString(2*getSymAxis() - paired[0]->getAxis()) << ")"; @@ -199,7 +204,7 @@ namespace Katana { _valid = false; } } else { - if (paired[0]->getAxis() != paired[1]->getAxis()) { + if ( std::abs( paired[0]->getAxis() != paired[1]->getAxis() ) > 2*vPitch ) { errors.newline() << "Axis mismatch index " << index << " " << DbU::getValueString(paired[1]->getAxis()) << " (should be:" << DbU::getValueString(paired[0]->getAxis()) << ")"; @@ -217,10 +222,10 @@ namespace Katana { errors.newline(); if (errors.size()) { - cmess2 << " pairing failed." << endl; + //cmess2 << " pairing failed." << endl; errors.print( cmess2 ); } else { - cmess2 << " paired." << endl; + //cmess2 << " paired." << endl; } return _valid; diff --git a/katana/src/GraphicKatanaEngine.cpp b/katana/src/GraphicKatanaEngine.cpp index 1a7ff74d..a6b03a0b 100644 --- a/katana/src/GraphicKatanaEngine.cpp +++ b/katana/src/GraphicKatanaEngine.cpp @@ -275,9 +275,10 @@ namespace Katana { KatanaEngine* katana = getForFramework( NoFlags ); if (katana) { katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); - katana->runTest(); + // Now done through Horus. + //katana->runTest(); katana->runNegociate( Flags::SymmetricStage ); - katana->runNegociate(); + //katana->runNegociate(); } } diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index 570259e5..78cf667b 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -95,7 +95,7 @@ namespace Katana { if (not _segment) throw Error( "Manipulator::Manipulator(): cannot build upon a NULL TrackElement." ); - DebugSession::open( _segment->getNet(), 149, 160 ); + DebugSession::open( _segment->getNet(), 156, 160 ); _data = _segment->getDataNegociate(); if (_data) _event = _data->getRoutingEvent(); @@ -635,7 +635,8 @@ namespace Katana { bool rightIntrication = false; bool success = true; - cdebug_log(159,0) << "Manipulator::insertInTrack() - " << toFree << endl; + cdebug_log(159,1) << "Manipulator::insertInTrack(size_t) - " << toFree << endl; + cdebug_log(159,0) << _segment << endl; for ( size_t i = begin ; success && (i < end) ; i++ ) { TrackElement* segment2 = track->getSegment(i); @@ -748,6 +749,10 @@ namespace Katana { } } if ( shrinkLeft ) { + cdebug_log(159,0) << "Move PP to right: " + << DbU::getValueString(toFree.getVMax()) << " + " + << DbU::getValueString(getPPitch()/2) + << endl; if ( not (success=Manipulator(segment3,_fsm) .ripup( SegmentAction::OtherRipupPerpandAndPushAside , toFree.getVMax() + getPPitch()/2 @@ -763,8 +768,7 @@ namespace Katana { } } else { if ( not (success=Manipulator(segment3,_fsm).ripup( SegmentAction::OtherRipup - | SegmentAction::EventLevel3 - )) ) + | SegmentAction::EventLevel3 )) ) break; } } @@ -774,10 +778,10 @@ namespace Katana { if ( success ) { cdebug_log(159,0) << "Manipulator::insertInTrack() success" << endl; - _fsm.setState ( SegmentFsm::OtherRipup ); - _fsm.addAction ( _segment - , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 - , _fsm.getCost(itrack).getTrack()->getAxis() ); + _fsm.setState ( SegmentFsm::OtherRipup ); + _fsm.addAction( _segment + , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 + , _fsm.getCost(itrack).getTrack()->getAxis() ); unsigned int flags = 0; if ( rightIntrication ) flags |= RightAxisHint; @@ -787,6 +791,7 @@ namespace Katana { } else _fsm.clearActions (); + cdebug_tabw(159,-1); return success; } @@ -802,7 +807,7 @@ namespace Katana { set canonicals; bool success = true; - cdebug_log(159,0) << "Manipulator::forceToTrack() - " << toFree << endl; + cdebug_log(159,1) << "Manipulator::forceToTrack(size_t) - " << toFree << endl; for ( size_t i=begin ; success and (i < end) ; ++i ) { TrackElement* segment2 = track->getSegment(i); @@ -829,7 +834,7 @@ namespace Katana { canonicals.clear(); for( TrackElement* segment3 - : segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { + : segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { DataNegociate* data3 = segment3->getDataNegociate(); if (not data3) continue; @@ -848,6 +853,7 @@ namespace Katana { , _fsm.getCost(itrack).getTrack()->getAxis() ); } + cdebug_tabw(159,-1); return success; } @@ -926,15 +932,15 @@ namespace Katana { { cdebug_log(159,1) << "Manipulator::forceOverLocals()" << endl; - vector& costs = _fsm.getCosts(); + vector< array >& costs = _fsm.getCosts(); size_t itrack = 0; for ( ; itrack " << fork << endl; + cdebug_log(159,0) << "Reschedule: cancelled (Unimplemented) -> " << fork << endl; return NULL; } if (not isProcessed()) { fork = this; - cdebug_log(159,0) << "Reschedule/Self: " - << " -> " - << eventLevel << ":" << fork << endl; + cdebug_log(159,0) << "Reschedule/Self: -> " + << eventLevel << ":" << fork << endl; } else { fork = clone(); fork->_processed = false; _segment->getDataNegociate()->setRoutingEvent( fork ); - cdebug_log(159,0) << "Reschedule/Fork: " - << " -> " << fork << endl; + cdebug_log(159,0) << "Reschedule/Fork: -> " << fork << endl; } if (fork->_eventLevel < eventLevel) @@ -393,7 +390,7 @@ namespace Katana { #endif } - DebugSession::open( _segment->getNet(), 149, 160 ); + DebugSession::open( _segment->getNet(), 156, 160 ); cdebug_log(9000,0) << "Deter| Event " << getProcesseds() @@ -418,6 +415,9 @@ namespace Katana { if ( isProcessed() or isDisabled() ) { cdebug_log(159,0) << "Already processed or disabled." << endl; } else { + if (_segment->hasSymmetric()) { + } + setProcessed(); setTimeStamp( _processeds ); @@ -460,7 +460,7 @@ namespace Katana { cdebug_tabw(159,1); - fsm.getData()->incRipupCount(); + fsm.incRipupCount(); cdebug_log(159,0) << "| Candidate Tracks:" << endl; size_t itrack = 0; @@ -468,22 +468,16 @@ namespace Katana { cdebug_log(159,0) << "| " << itrack << ":" << fsm.getCost(itrack) << endl; itrack = 0; - if ( (not isOverConstrained()) and Manipulator(_segment,fsm).canRipup() ) { + if ( (not isOverConstrained()) and fsm.canRipup() ) { if (fsm.getCosts().size() and fsm.getCost(itrack).isFree()) { cdebug_log(159,0) << "Insert in free space " << this << endl; - resetInsertState(); - - _axisHistory = _segment->getAxis(); - _eventLevel = 0; - cdebug_log(9000,0) << "Deter| addInsertEvent() @" << fsm.getCost(itrack).getTrack() << endl; - Session::addInsertEvent( _segment, fsm.getCost(itrack).getTrack() ); - fsm.setState( SegmentFsm::SelfInserted ); + fsm.bindToTrack( itrack ); } else { // Do ripup. if (fsm.getState() == SegmentFsm::EmptyTrackList) { - Manipulator(_segment,fsm).ripupPerpandiculars(); + fsm.ripupPerpandiculars(); } else { - if (Manipulator(_segment,fsm).canRipup(Manipulator::NotOnLastRipup)) { + if (fsm.canRipup(Manipulator::NotOnLastRipup)) { if (cdebug.enabled(9000)) { for ( itrack=0 ; itracksetState( DataNegociate::Slacken ); + fsm.setDataState( DataNegociate::Slacken ); } if (not fsm.slackenTopology()) { fsm.setState( SegmentFsm::SelfMaximumSlack ); @@ -545,8 +539,7 @@ namespace Katana { and (fsm.getCost(0).getTrack() != _segment->getTrack()) ) { cerr << "_processPack(): move to " << fsm.getCost(0).getTrack() << endl; - Session::addMoveEvent( _segment, fsm.getCost(0).getTrack() ); - fsm.setState( SegmentFsm::SelfInserted ); + fsm.moveToTrack( 0 ); } } @@ -563,6 +556,7 @@ namespace Katana { SegmentFsm fsm ( this, queue, history ); if (fsm.getState() == SegmentFsm::MissingData ) return; if (fsm.getState() == SegmentFsm::EmptyTrackList) return; + if (fsm.isSymmetric()) return; cdebug_tabw(159,1); for ( size_t i = 0 ; i < fsm.getCosts().size() ; i++ ) @@ -571,8 +565,7 @@ namespace Katana { if (fsm.getCosts().size() and fsm.getCost(0).isFree()) { cdebug_log(159,0) << "Insert in free space." << endl; - Session::addInsertEvent( _segment, fsm.getCost(0).getTrack() ); - fsm.setState( SegmentFsm::SelfInserted ); + fsm.bindToTrack( 0 ); } else { switch ( fsm.getData()->getStateCount() ) { case 1: @@ -599,7 +592,7 @@ namespace Katana { void RoutingEvent::revalidate () { - DebugSession::open( _segment->getNet(), 150, 160 ); + DebugSession::open( _segment->getNet(), 156, 160 ); cdebug_log(159,1) << "RoutingEvent::revalidate() - " << this << endl; diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index 119b788b..8748fe49 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -36,6 +36,26 @@ namespace { using namespace Katana; +// ------------------------------------------------------------------- +// Class : "CompareCostArray". + + class CompareCostArray { + public: + inline CompareCostArray ( unsigned int flags=0 ); + inline bool operator() ( const array& lhs, const array& rhs ); + private: + TrackCost::Compare _compare; + }; + + + inline CompareCostArray::CompareCostArray ( unsigned int flags ) + : _compare(flags) + { } + + inline bool CompareCostArray::operator() ( const array& lhs, const array& rhs ) + { return _compare( lhs[0], rhs[0] ); } + + // ------------------------------------------------------------------- // Class : "Cs1Candidate". @@ -363,7 +383,7 @@ namespace Katana { // "_immediate" ripup flags was associated with "perpandicular", as they // must be re-inserted *before* any parallel. Must look to solve the redundancy. - DebugSession::open( _segment->getNet(), 150, 160 ); + DebugSession::open( _segment->getNet(), 156, 160 ); if (_type & Perpandicular) { cdebug_log(159,0) << "* Riping Pp " << _segment << endl; @@ -438,43 +458,85 @@ namespace Katana { // Class : "SegmentFsm". - SegmentFsm::SegmentFsm ( RoutingEvent* event, RoutingEventQueue& queue, RoutingEventHistory& history ) - : _event (event) + SegmentFsm::SegmentFsm ( RoutingEvent* event1 + , RoutingEventQueue& queue + , RoutingEventHistory& history ) + : _event1 (event1) + , _event2 (NULL) , _queue (queue) , _history (history) , _state (0) - , _data (NULL) + , _data1 (NULL) + , _data2 (NULL) , _constraint () , _optimal () , _costs () , _actions () , _fullBlocked(true) + , _sameAxis (false) + , _useEvent2 (false) { - TrackElement* segment = _event->getSegment(); - unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer()); - _event->setTracksFree( 0 ); + DataSymmetric* symData = NULL; + TrackElement* segment1 = _event1->getSegment(); + TrackElement* segment2 = segment1->getSymmetric(); + unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment1->getLayer()); + _event1->setTracksFree( 0 ); - _data = segment->getDataNegociate(); - if (not _data) { + _data1 = segment1->getDataNegociate(); + if (not _data1) { _state = MissingData; return; } - _data->update(); - _event->revalidate(); + _data1->update(); + _event1->revalidate(); - _constraint = _event->getConstraints(); - _optimal = _event->getOptimal(); + if (segment2) { + symData = Session::getKatanaEngine()->getDataSymmetric( segment1->getNet() ); - const Interval& perpandicular = _event->getPerpandicularFree(); + _data2 = segment2->getDataNegociate(); + if (not _data2 or not symData) { + _state = MissingData; + return; + } + + _event2 = _data2->getRoutingEvent(); + _event2->setTracksFree( 0 ); + + _data2->update(); + _event2->revalidate(); + + _sameAxis = (segment1->isVertical() xor symData->isSymVertical()); + } + + Interval perpandicular = _event1->getPerpandicularFree(); + cdebug_log(159,0) << "* Perpandicular (master): " << perpandicular << endl; + + _constraint = _event1->getConstraints(); + _optimal = _event1->getOptimal(); + if (_event2) { + if (_sameAxis) { + _constraint .intersection( _event2->getConstraints() ); + perpandicular.intersection( _event2->getPerpandicularFree() ); + + cdebug_log(159,0) << "* Perpandicular (slave): same axis " + << _event2->getPerpandicularFree() << endl; + } else { + _constraint .intersection( symData->getSymmetrical( _event2->getConstraints() ) ); + perpandicular.intersection( symData->getSymmetrical( _event2->getPerpandicularFree() ) ); + + cdebug_log(159,0) << "* Perpandicular (slave): PP axis " + << symData->getSymmetrical(_event2->getPerpandicularFree()) << endl; + } + } cdebug_log(159,0) << "Anabatic intervals:" << endl; cdebug_log(159,0) << "* Optimal: " << _optimal << endl; cdebug_log(159,0) << "* Constraints: " << _constraint << endl; cdebug_log(159,0) << "* Perpandicular: " << perpandicular << endl; - cdebug_log(159,0) << "* AxisHint: " << DbU::getValueString(_event->getAxisHint()) << endl; + cdebug_log(159,0) << "* AxisHint: " << DbU::getValueString(_event1->getAxisHint()) << endl; - if (_event->getTracksNb()) { + if (_event1->getTracksNb()) { if (_constraint.getIntersection(perpandicular).isEmpty()) { cdebug_log(159,0) << "Perpandicular free is too tight." << endl; _state = EmptyTrackList; @@ -487,46 +549,64 @@ namespace Katana { if (_state == EmptyTrackList) return; - cdebug_log(159,0) << "Negociate intervals:" << endl; - cdebug_log(159,0) << "* Optimal: " << _optimal << endl; - cdebug_log(159,1) << "* Constraints: " << _constraint << endl; + cdebug_log(159,0) << "Negociate intervals:" << endl; + cdebug_log(159,0) << "* Optimal: " << _optimal << endl; + cdebug_log(159,0) << "* Constraints: " << _constraint << endl; + cdebug_log(159,1) << "* _sameAxis: " << _sameAxis << endl; // if ( segment->isLocal() and (_data->getState() >= DataNegociate::MaximumSlack) ) // _constraint.inflate ( 0, DbU::lambda(1.0) ); bool inLocalDepth = (depth < 3); - bool isOneLocalTrack = (segment->isLocal()) - and (segment->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0); + bool isOneLocalTrack = (segment1->isLocal()) + and (segment1->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0); - RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment->getLayer()); - for ( Track* track : Tracks_Range::get(plane,_constraint) ) { + RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment1->getLayer()); + for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) { unsigned int costflags = 0; - costflags |= (segment->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0; + costflags |= (segment1->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0; - if (not segment->isReduced()) - _costs.push_back( track->getOverlapCost(segment,costflags) ); - else - _costs.push_back( TrackCost(track,segment->getNet()) ); - _costs.back().setAxisWeight ( _event->getAxisWeight(track->getAxis()) ); - _costs.back().incDeltaPerpand( _data->getWiringDelta(track->getAxis()) ); - if (segment->isGlobal()) { - cdebug_log(9000,0) << "Deter| setForGlobal() on " << track << endl; - _costs.back().setForGlobal(); + Track* track2 = NULL; + if (_event2) { + track2 = + (_sameAxis) ? track1 : plane->getTrackByPosition( symData->getSymmetrical( track1->getAxis() ) ); } - if ( inLocalDepth and (_costs.back().getDataState() == DataNegociate::MaximumSlack) ) - _costs.back().setInfinite(); + _costs.push_back( array( { TrackCost(NULL), TrackCost(NULL) } ) ); + if (not segment1->isReduced()) { + _costs.back()[0] = track1->getOverlapCost(segment1,costflags); + if (_event2) _costs.back()[1] = track2->getOverlapCost(segment2,costflags); + } else { + _costs.back()[0] = TrackCost(track1); + if (_event2) _costs.back()[1] = TrackCost(track2); + } + + _costs.back()[0].setAxisWeight ( _event1->getAxisWeight(track1->getAxis()) ); + _costs.back()[0].incDeltaPerpand( _data1->getWiringDelta(track1->getAxis()) ); + if (_event2) { + _costs.back()[1].setAxisWeight ( _event2->getAxisWeight(track2->getAxis()) ); + _costs.back()[1].incDeltaPerpand( _data2->getWiringDelta(track2->getAxis()) ); + _costs.back()[0].merge( _costs.back()[1] ); + } + + if (segment1->isGlobal()) { + cdebug_log(9000,0) << "Deter| setForGlobal() on " << track1 << endl; + _costs.back()[0].setForGlobal(); + } + + if ( inLocalDepth and (_costs.back()[0].getDataState() == DataNegociate::MaximumSlack) ) + _costs.back()[0].setInfinite(); if ( isOneLocalTrack - and _costs.back().isOverlapGlobal() - and (_costs.back().getDataState() >= DataNegociate::ConflictSolveByHistory) ) - _costs.back().setInfinite(); + and _costs.back()[0].isOverlapGlobal() + and (_costs.back()[0].getDataState() >= DataNegociate::ConflictSolveByHistory) ) + _costs.back()[0].setInfinite(); - _costs.back().consolidate(); - if ( _fullBlocked and (not _costs.back().isBlockage() and not _costs.back().isFixed()) ) + _costs.back()[0].consolidate(); + if ( _fullBlocked and (not _costs.back()[0].isBlockage() and not _costs.back()[0].isFixed()) ) _fullBlocked = false; - cdebug_log(159,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track << endl; + cdebug_log(155,0) << "| " << _costs.back()[0] << ((_fullBlocked)?" FB ": " -- ") << track1 << endl; } cdebug_tabw(159,-1); @@ -540,7 +620,7 @@ namespace Katana { // << _constraint << " " << "." << endl; } else { cerr << Bug( " %s Track_Range() failed to find Tracks in %s (they exists)." - , getString(segment).c_str() + , getString(segment1).c_str() , getString(_constraint).c_str() ) << endl; } @@ -548,10 +628,10 @@ namespace Katana { } unsigned int flags = 0; - flags |= (segment->isStrap()) ? TrackCost::IgnoreAxisWeight : 0; - flags |= (segment->isLocal() - and (_data->getState() < DataNegociate::Minimize) - and (_data->getRipupCount() < 5)) + flags |= (segment1->isStrap()) ? TrackCost::IgnoreAxisWeight : 0; + flags |= (segment1->isLocal() + and (_data1->getState() < DataNegociate::Minimize) + and (_data1->getRipupCount() < 5)) ? TrackCost::DiscardGlobals : 0; flags |= (RoutingEvent::getStage() == RoutingEvent::Repair) ? TrackCost::IgnoreSharedLength : 0; @@ -559,11 +639,23 @@ namespace Katana { cdebug_log(159,0) << "TrackCost::Compare() - DiscardGlobals" << endl; } - sort( _costs.begin(), _costs.end(), TrackCost::Compare(flags) ); + sort( _costs.begin(), _costs.end(), CompareCostArray(flags) ); size_t i=0; - for ( ; (i<_costs.size()) and _costs[i].isFree() ; i++ ); - _event->setTracksFree ( i ); + for ( ; (i<_costs.size()) and _costs[i][0].isFree() ; i++ ); + _event1->setTracksFree ( i ); + + if (_event2) { + for ( ; (i<_costs.size()) and _costs[i][1].isFree() ; i++ ); + _event2->setTracksFree ( i ); + } + } + + + void SegmentFsm::setDataState ( unsigned int state ) + { + _data1->setState( state ); + if (_data2) _data2->setState( state ); } @@ -581,7 +673,7 @@ namespace Katana { void SegmentFsm::doActions () { - cdebug_log(159,0) << "SegmentFsm::doActions() - " << _actions.size() << endl; + cdebug_log(159,1) << "SegmentFsm::doActions() - " << _actions.size() << endl; bool ripupOthersParallel = false; bool ripedByLocal = getEvent()->getSegment()->isLocal(); @@ -597,7 +689,7 @@ namespace Katana { if ( (_actions[i].getType() & SegmentAction::SelfInsert) and ripupOthersParallel ) _actions[i].setFlag ( SegmentAction::EventLevel3 ); - DebugSession::open ( _actions[i].getSegment()->getNet(), 150, 160 ); + DebugSession::open ( _actions[i].getSegment()->getNet(), 156, 160 ); if ( not _actions[i].doAction(_queue) ) { cinfo << "[INFO] Failed action on " << _actions[i].getSegment() << endl; } @@ -605,36 +697,113 @@ namespace Katana { } _actions.clear (); + cdebug_tabw(159,-1); + } + + + void SegmentFsm::incRipupCount () + { + _data1->incRipupCount(); + if (_data2) _data2->incRipupCount(); } bool SegmentFsm::insertInTrack ( size_t i ) { - cdebug_log(159,0) << "SegmentFsm::insertInTrack() istate:" << _event->getInsertState() + cdebug_log(159,0) << "SegmentFsm::insertInTrack() istate:" << _event1->getInsertState() << " track:" << i << endl; - _event->incInsertState(); - switch ( _event->getInsertState() ) { + bool success = true; + + _event1->incInsertState(); + switch ( _event1->getInsertState() ) { case 1: - if ( Manipulator(_event->getSegment(),*this).insertInTrack(i) ) return true; - _event->incInsertState(); + success = Manipulator(_event1->getSegment(),useEvent1()).insertInTrack(i); + success = success and (not _event2 or Manipulator(_event2->getSegment(),useEvent2()).insertInTrack(i)); + if (success) break; + _event1->incInsertState(); + clearActions(); case 2: - if ( Manipulator(_event->getSegment(),*this).shrinkToTrack(i) ) return true; - _event->incInsertState(); + success = Manipulator(_event1->getSegment(),useEvent1()).shrinkToTrack(i); + success = success and (not _event2 or Manipulator(_event2->getSegment(),useEvent2()).shrinkToTrack(i)); + if (success) break; + _event1->incInsertState(); + clearActions(); case 3: - if ( Manipulator(_event->getSegment(),*this).forceToTrack(i) ) return true; - _event->incInsertState(); + success = Manipulator(_event1->getSegment(),useEvent1()).forceToTrack(i); + success = success and (not _event2 or Manipulator(_event2->getSegment(),useEvent2()).forceToTrack(i)); + if (success) break; + _event1->incInsertState(); + clearActions(); } - return false; + + useEvent1(); + if (_event2) _event2->setInsertState( _event1->getInsertState() ); + + return success; } + void SegmentFsm::bindToTrack ( size_t i ) + { + cdebug_log(159,0) << "SegmentFsm::bindToTrack() :" << " track:" << i << endl; + + _event1->resetInsertState(); + _event1->updateAxisHistory(); + _event1->setEventLevel( 0 ); + + cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; + Session::addInsertEvent( getSegment1(), getCost1(i).getTrack() ); + + if (_event2) { + _event2->resetInsertState(); + _event2->updateAxisHistory(); + _event2->setEventLevel( 0 ); + _event2->setProcessed( true ); + + cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; + Session::addInsertEvent( getSegment2(), getCost2(i).getTrack() ); + } + + setState( SegmentFsm::SelfInserted ); + } + + + void SegmentFsm::moveToTrack ( size_t i ) + { + cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl; + + Session::addMoveEvent( getSegment1(), getCost1(i).getTrack() ); + + if (_event2) { + cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; + Session::addMoveEvent( getSegment2(), getCost2(i).getTrack() ); + } + + setState( SegmentFsm::SelfInserted ); + } + + + void SegmentFsm::ripupPerpandiculars () + { + Manipulator(getSegment1(),*this).ripupPerpandiculars(); + if (_event2) + Manipulator(getSegment2(),*this).ripupPerpandiculars(); + } + + + bool SegmentFsm::canRipup ( unsigned int flags ) + { + return Manipulator(getSegment1(),*this).canRipup(flags) + and (not _event2 or Manipulator(getSegment2(),*this).canRipup(flags)); + } + bool SegmentFsm::conflictSolveByHistory () { bool success = false; - RipupHistory ripupHistory ( _event ); + RipupHistory ripupHistory ( _event1 ); RoutingEvent* event; - TrackElement* segment = _event->getSegment(); + TrackElement* segment = getEvent()->getSegment(); cdebug_log(159,0) << "SegmentFsm::conflictSolveByHistory()" << endl; @@ -719,11 +888,11 @@ namespace Katana { bool success = false; Interval constraints; vector candidates; - TrackElement* segment = _event->getSegment(); + TrackElement* segment = getEvent()->getSegment(); bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5,Flags::NoFlags) : segment->canMoveUp(1.0,Flags::CheckLowDensity); // MARK 1 unsigned int relaxFlags = Manipulator::NoDoglegReuse - | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand - : Manipulator::NoExpand); + | ((_data1 and (_data1->getStateCount() < 2)) ? Manipulator::AllowExpand + : Manipulator::NoExpand); cdebug_log(159,0) << "SegmentFsm::conflictSolveByPlaceds()" << endl; cdebug_log(159,0) << "| Candidates Tracks: " << endl; @@ -942,7 +1111,7 @@ namespace Katana { size_t itrack = 0; #if THIS_IS_DISABLED - TrackElement* segment = _event->getSegment(); + TrackElement* segment = getEvent()->getSegment(); for ( ; itrackgetSegment(); - DataNegociate* data = segment->getDataNegociate (); + TrackElement* segment1 = getSegment1(); unsigned int actionFlags = SegmentAction::SelfInsert|SegmentAction::EventLevel5; - DebugSession::open( segment->getNet(), 150, 160 ); - cdebug_log(159,1) << "Slacken Topology for " << segment->getNet() - << " " << segment << endl; + DebugSession::open( segment1->getNet(), 156, 160 ); + cdebug_log(159,1) << "Slacken Topology for " << segment1->getNet() + << " " << segment1 << endl; - if (not segment or not data) { cdebug_tabw(159,-1); DebugSession::close(); return false; } + if (_data2) { + cdebug_log(159,0) << "Symmetric segments are not allowed to slacken (yet)" << endl; + cdebug_tabw(159,-1); + DebugSession::close(); + return false; + } - _event->resetInsertState(); - data->resetRipupCount(); + if (not segment1 or not _data1) { cdebug_tabw(159,-1); DebugSession::close(); return false; } - if (segment->isStrap()) { success = _slackenStrap ( segment, data, flags ); } - else if (segment->isLocal()) { success = _slackenLocal ( segment, data, flags ); } - else { success = _slackenGlobal( segment, data, flags ); } + _event1->resetInsertState(); + _data1->resetRipupCount(); + if (_event2) { + _event2->resetInsertState(); + _data2->resetRipupCount(); + } + + if (segment1->isStrap()) { success = _slackenStrap ( segment1, _data1, flags ); } + else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); } + else { success = _slackenGlobal( segment1, _data1, flags ); } if (success) { actionFlags |= SegmentAction::ResetRipup; - addAction( segment, actionFlags ); + addAction( segment1, actionFlags ); } else { clearActions(); - if (data->getState() == DataNegociate::Unimplemented) { - cinfo << "[UNSOLVED] " << segment << " unable to slacken topology." << endl; + if (_data1->getState() == DataNegociate::Unimplemented) { + cinfo << "[UNSOLVED] " << segment1 << " unable to slacken topology." << endl; } } diff --git a/katana/src/SymmetricRoute.cpp b/katana/src/SymmetricRoute.cpp index 933d9347..4c8296d8 100644 --- a/katana/src/SymmetricRoute.cpp +++ b/katana/src/SymmetricRoute.cpp @@ -50,8 +50,9 @@ namespace { using Anabatic::AutoContactTerminal; using Anabatic::AutoSegment; using Anabatic::AutoSegmentFlag; - using Katana::KatanaEngine; + using Katana::TrackElement; using Katana::DataSymmetric; + using Katana::KatanaEngine; using Katana::Session; @@ -111,6 +112,7 @@ namespace { void _doDualPairing (); AutoContactTerminal* _getSymmetricTerminal ( AutoContactTerminal* masterContact ); Component* _findMiddleComponent (); + void _associate (); private: KatanaEngine* _katana; AutoSegment* _seed; @@ -138,16 +140,21 @@ namespace { DebugSession::open( _data->getNet(), 144, 146 ); + // Temporary. + _data->setSymAxis( _katana->getCell()->getAbutmentBox().getCenter().getX() ); + cmess2 << " - Net: \"" << _data->getNet()->getName() << "\" "; cmess2 << "@" << DbU::getValueString(_data->getSymAxis()) << " "; cmess2 << (_data->isSymVertical() ? "Vertical" : "Horizontal") << " "; if (_data->getSymNet()) cmess2 << "(paired: \"" << _data->getSymNet()->getName() << "\")"; else cmess2 << "(self symmetric)"; + cmess2 << endl; if (_data->getSymNet()) _doDualPairing(); else _doSelfPairing(); if (_data->isValid()) _data->checkPairing(); + _associate(); DebugSession::close(); @@ -201,9 +208,7 @@ namespace { AutoContactTerminal* TopologicalPairing::_getSymmetricTerminal ( AutoContactTerminal* masterContact ) { - Point mirror = masterContact->getCenter(); - _data->getSymmetrical( mirror ); - + Point mirror = _data->getSymmetrical( masterContact->getCenter() ); GCell* mirrorGCell = _katana->getGCellUnder( mirror ); if (not mirrorGCell) { cerr << Error( "getSymmetricTerminal() No GCell under symmetric position (%s,%s)." @@ -221,7 +226,10 @@ namespace { } } - cerr << Error( "getSymmetricTerminal() Missing terminal contact in symmetric GCell." + cerr << Error( "getSymmetricTerminal() Missing terminal contact in symmetric GCell.\n" + " master:%s\n" + " mirror:%s" + , getString(masterContact).c_str(), getString(mirrorGCell).c_str() ) << endl; _data->setValid( false ); @@ -352,6 +360,30 @@ namespace { } + void TopologicalPairing::_associate () + { + cdebug_log(144,1) << "TopologicalPairing::_associate()" << endl; + + //cmess1 << " - Associating symmetrics." << endl; + + if (not _data->isValid()) return; + + const DataSymmetric::Paireds& paireds = _data->getPaireds(); + for ( auto sympair : paireds ) { + if (not sympair[0]->isCanonical() or not sympair[1]->isCanonical()) continue; + + TrackElement* trackSegment0 = Session::lookup( sympair[0] ); + TrackElement* trackSegment1 = Session::lookup( sympair[1] ); + + if (not trackSegment0 or not trackSegment1) continue; + + trackSegment0->setSymmetric( trackSegment1 ); + trackSegment1->setSymmetric( trackSegment0 ); + } + + cdebug_tabw(144,-1); + } + } // Anonymous namespace. @@ -363,6 +395,7 @@ namespace Katana { void KatanaEngine::runSymmetricRouter () { for ( Net* net : getCell()->getNets() ) { + if (not NetRoutingExtension::isSymmetric(net)) continue; TopologicalPairing(this,net).doPairing(); } } diff --git a/katana/src/TrackCost.cpp b/katana/src/TrackCost.cpp index 223b28be..2f6501de 100644 --- a/katana/src/TrackCost.cpp +++ b/katana/src/TrackCost.cpp @@ -31,7 +31,7 @@ namespace Katana { // ------------------------------------------------------------------- // Class : "TrackCost". - TrackCost::TrackCost ( Track* track, Net* net ) + TrackCost::TrackCost ( Track* track ) : _flags (ZeroCost) , _track (track) , _begin (Track::npos) @@ -209,6 +209,19 @@ namespace Katana { } + void TrackCost::merge ( const TrackCost& other ) + { + _terminals += other._terminals; + _delta += other._delta; + _deltaShared += other._deltaShared; + _deltaPerpand += other._deltaPerpand; + _axisWeight += other._axisWeight; + _distanceToFixed = std::min( _distanceToFixed, other._distanceToFixed ); + _longuestOverlap = std::min( _longuestOverlap, other._longuestOverlap ); + _dataState = std::max( _dataState, other._dataState ); + } + + string TrackCost::_getString () const { string s = "<" + _getTypeName(); diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index effc22d1..8ea7a561 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -145,6 +145,7 @@ namespace Katana { bool TrackElement::isUTurn () const { return false; } bool TrackElement::isUserDefined () const { return false; } // Predicates. + bool TrackElement::hasSymmetric () const { return false; } bool TrackElement::canSlacken () const { return false; } bool TrackElement::canPivotUp ( float, unsigned int ) const { return false; }; bool TrackElement::canPivotDown ( float, unsigned int ) const { return false; }; @@ -168,8 +169,10 @@ namespace Katana { TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; } TrackElement* TrackElement::getSourceDogleg () { return NULL; } TrackElement* TrackElement::getTargetDogleg () { return NULL; } + TrackElement* TrackElement::getSymmetric () { return NULL; } // Mutators. void TrackElement::setTrack ( Track* track ) { _track = track; } + void TrackElement::setSymmetric ( TrackElement* ) { } void TrackElement::updateFreedomDegree () { } void TrackElement::setDoglegLevel ( unsigned int ) { } void TrackElement::swapTrack ( TrackElement* ) { } diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 232af4bc..c76f6e3f 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -61,6 +61,7 @@ namespace Katana { TrackSegment::TrackSegment ( AutoSegment* segment, Track* track ) : TrackElement (track) , _base (segment) + , _symmetric (NULL) , _freedomDegree(0) , _ppitch (0) , _data (NULL) @@ -161,6 +162,7 @@ namespace Katana { bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); } bool TrackSegment::isUTurn () const { return _base->isUTurn(); } // Predicates. + bool TrackSegment::hasSymmetric () const { return _symmetric != NULL; } // Accessors. unsigned long TrackSegment::getId () const { return _base->getId(); } Flags TrackSegment::getDirection () const { return _base->getDirection(); } @@ -174,6 +176,7 @@ namespace Katana { Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); } Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); } TrackElement* TrackSegment::getCanonical ( Interval& i ) { return Session::lookup( _base->getCanonical(i)->base() ); } + TrackElement* TrackSegment::getSymmetric () { return _symmetric; } TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); } // Mutators. void TrackSegment::invalidate () { setFlags( TElemInvalidated ); _base->invalidate(); } @@ -231,22 +234,22 @@ namespace Katana { GCell* sourceGCell = base()->getAutoSource()->getGCell(); GCell* targetGCell = base()->getAutoTarget()->getGCell(); - cdebug_log(159,0) << "getGCells(): sourceGCell: " << sourceGCell << endl; - cdebug_log(159,0) << "getGCells(): targetGCell: " << targetGCell << endl; + cdebug_log(155,0) << "getGCells(): sourceGCell: " << sourceGCell << endl; + cdebug_log(155,0) << "getGCells(): targetGCell: " << targetGCell << endl; for ( AutoSegment* segment : base()->getAligneds() ) { - cdebug_log(159,0) << "| " << segment << endl; + cdebug_log(155,0) << "| " << segment << endl; Anabatic::GCell* gcell = segment->getAutoSource()->getGCell(); if (isLess(gcell,sourceGCell,direction)) { sourceGCell = gcell; - cdebug_log(159,0) << "getGCells(): new sourceGCell: " << sourceGCell << endl; + cdebug_log(155,0) << "getGCells(): new sourceGCell: " << sourceGCell << endl; } gcell = segment->getAutoTarget()->getGCell(); if (isGreater(gcell,targetGCell,direction)) { targetGCell = gcell; - cdebug_log(159,0) << "getGCells(): new targetGCell: " << targetGCell << endl; + cdebug_log(155,0) << "getGCells(): new targetGCell: " << targetGCell << endl; } } @@ -256,12 +259,12 @@ namespace Katana { Flags side = (direction & Flags::Horizontal) ? Flags::EastSide : Flags::NorthSide; DbU::Unit axis = getAxis(); - cdebug_log(159,0) << "* dir:" << side._getString() << " @" << DbU::getValueString(axis) << endl; + cdebug_log(155,0) << "* dir:" << side._getString() << " @" << DbU::getValueString(axis) << endl; gcells.push_back( sourceGCell ); while ( sourceGCell != targetGCell ) { sourceGCell = sourceGCell->getNeighborAt( direction, axis ); - cdebug_log(159,0) << "| " << sourceGCell << endl; + cdebug_log(155,0) << "| " << sourceGCell << endl; if (not sourceGCell) break; gcells.push_back( sourceGCell ); @@ -315,6 +318,10 @@ namespace Katana { { TrackElement::setTrack( track ); } + void TrackSegment::setSymmetric ( TrackElement* segment ) + { _symmetric = dynamic_cast( segment ); } + + void TrackSegment::detach () { cdebug_log(159,0) << "TrackSegment::detach() - " << endl; @@ -880,7 +887,8 @@ namespace Katana { Record* TrackSegment::_getRecord () const { Record* record = TrackElement::_getRecord(); - record->add( getSlot( "_base", _base ) ); + record->add( getSlot( "_base" , _base ) ); + record->add( getSlot( "_symmetric", _symmetric ) ); return record; } diff --git a/katana/src/TrackSegmentCost.cpp b/katana/src/TrackSegmentCost.cpp index d153050c..ba969a41 100644 --- a/katana/src/TrackSegmentCost.cpp +++ b/katana/src/TrackSegmentCost.cpp @@ -73,7 +73,7 @@ namespace Katana { void TrackSegmentCost::update ( TrackElement* trackSegment ) { - DebugSession::open ( trackSegment->getNet(), 150, 160 ); + DebugSession::open ( trackSegment->getNet(), 156, 160 ); cdebug_log(159,1) << "TrackSegmentCost::update() - " << trackSegment << endl; diff --git a/katana/src/Tracks.cpp b/katana/src/Tracks.cpp index d9bbb2c4..a0469b35 100644 --- a/katana/src/Tracks.cpp +++ b/katana/src/Tracks.cpp @@ -38,15 +38,15 @@ namespace Katana { : Hurricane::Locator() , _constraints (constraints) { - cdebug_log(159,0) << "Tracks_Range::Locator()" << endl; - cdebug_log(159,0) << "* Constraints: " << _constraints << endl; + cdebug_log(155,0) << "Tracks_Range::Locator()" << endl; + cdebug_log(155,0) << "* Constraints: " << _constraints << endl; _track = routingPlane->getTrackByPosition ( _constraints.getVMin() ); if ( _track and (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNextTrack(); if ( _track and (_track->getAxis() > _constraints.getVMax()) ) _track = NULL; - cdebug_log(159,0) << "_track: " << _track << endl;; + cdebug_log(155,0) << "_track: " << _track << endl;; } @@ -147,9 +147,9 @@ namespace Katana { , _inMinOptimal(true) , _inMaxOptimal(true) { - cdebug_log(159,0) << "Tracks_Spiral::Locator()" << endl; - cdebug_log(159,0) << "* Optimal: " << _optimal << endl; - cdebug_log(159,0) << "* Constraints: " << _constraints << endl; + cdebug_log(155,0) << "Tracks_Spiral::Locator()" << endl; + cdebug_log(155,0) << "* Optimal: " << _optimal << endl; + cdebug_log(155,0) << "* Constraints: " << _constraints << endl; _minTrack = _maxTrack = routingPlane->getTrackByPosition ( _optimal.getCenter() ); @@ -169,8 +169,8 @@ namespace Katana { if ( _minTrack && (_minTrack->getAxis() < _optimal.getVMin()) ) _inMinOptimal = false; if ( _maxTrack && (_maxTrack->getAxis() > _optimal.getVMax()) ) _inMaxOptimal = false; - cdebug_log(159,0) << "_minTrack: " << _minTrack << endl;; - cdebug_log(159,0) << "_maxTrack: " << _maxTrack << endl;; + cdebug_log(155,0) << "_minTrack: " << _minTrack << endl;; + cdebug_log(155,0) << "_maxTrack: " << _maxTrack << endl;; } @@ -210,13 +210,13 @@ namespace Katana { void Tracks_Spiral::Locator::progress () { - cdebug_log(159,1) << "Track_Spiral::progress() - State:" << endl; - cdebug_log(159,0) << _onMin + cdebug_log(155,1) << "Track_Spiral::progress() - State:" << endl; + cdebug_log(155,0) << _onMin << " " << _minTrack << " " << _maxTrack << endl; if ( !isValid() ) { - cdebug_tabw(159,-1); + cdebug_tabw(155,-1); return; } @@ -245,10 +245,10 @@ namespace Katana { } } - cdebug_log(159,0) << _onMin - << " " << _minTrack - << " " << _maxTrack << endl; - cdebug_tabw(159,-1); + cdebug_log(155,0) << _onMin + << " " << _minTrack + << " " << _maxTrack << endl; + cdebug_tabw(155,-1); } diff --git a/katana/src/katana/DataSymmetric.h b/katana/src/katana/DataSymmetric.h index 547269ff..3f95a5a4 100644 --- a/katana/src/katana/DataSymmetric.h +++ b/katana/src/katana/DataSymmetric.h @@ -37,6 +37,7 @@ namespace Katana { using Hurricane::Record; using Hurricane::DbU; using Hurricane::Point; + using Hurricane::Interval; using Hurricane::Net; using Hurricane::NetRoutingState; using Hurricane::NetRoutingExtension; @@ -44,6 +45,8 @@ namespace Katana { class DataSymmetric { + public: + typedef std::vector< std::array > Paireds; public: static DataSymmetric* create ( Net* ); public: @@ -52,11 +55,15 @@ namespace Katana { inline Net* getNet () const; inline DbU::Unit getSymAxis () const; inline Net* getSymNet () const; - inline Point& getSymmetrical ( Point& ) const; + inline const Paireds& getPaireds () const; + inline DbU::Unit getSymmetrical ( DbU::Unit ) const; + inline Point getSymmetrical ( const Point& ) const; + inline Interval getSymmetrical ( const Interval& ) const; AutoSegment* getSymmetrical ( AutoSegment* ) const; void addSymmetrical ( AutoSegment* ); inline void addReference ( AutoSegment* ); inline void setValid ( bool ); + inline void setSymAxis ( DbU::Unit ); bool checkPairing (); void print ( std::ostream& ) const; Record* _getRecord () const; @@ -64,28 +71,45 @@ namespace Katana { private: DataSymmetric ( Net* ); private: - bool _valid; - Net* _net; - Net* _symNet; - NetRoutingState* _state; - std::vector< std::array > _paireds; - size_t _symIndex; + bool _valid; + Net* _net; + Net* _symNet; + NetRoutingState* _state; + Paireds _paireds; + size_t _symIndex; }; - inline bool DataSymmetric::isValid () const { return _valid; } - inline bool DataSymmetric::isSymVertical () const { return _state->isSymVertical(); } - inline Net* DataSymmetric::getNet () const { return _net; } - inline DbU::Unit DataSymmetric::getSymAxis () const { return _state->getSymAxis(); } - inline Net* DataSymmetric::getSymNet () const { return _symNet; } - inline void DataSymmetric::addReference ( AutoSegment* segment ) { _paireds.push_back( {segment,NULL} ); } - inline void DataSymmetric::setValid ( bool state ) { _valid = state; } + inline bool DataSymmetric::isValid () const { return _valid; } + inline bool DataSymmetric::isSymVertical () const { return _state->isSymVertical(); } + inline const DataSymmetric::Paireds& DataSymmetric::getPaireds () const { return _paireds; } + inline Net* DataSymmetric::getNet () const { return _net; } + inline DbU::Unit DataSymmetric::getSymAxis () const { return _state->getSymAxis(); } + inline void DataSymmetric::setSymAxis ( DbU::Unit axis ) { _state->setSymAxis(axis); } + inline Net* DataSymmetric::getSymNet () const { return _symNet; } + inline void DataSymmetric::addReference ( AutoSegment* segment ) { _paireds.push_back( {segment,NULL} ); } + inline void DataSymmetric::setValid ( bool state ) { _valid = state; } - inline Point& DataSymmetric::getSymmetrical ( Point& point ) const + inline DbU::Unit DataSymmetric::getSymmetrical ( DbU::Unit pos ) const + { return 2*getSymAxis() - pos; } + + inline Point DataSymmetric::getSymmetrical ( const Point& point ) const { - if (_state->isSymVertical()) point.setX( 2*getSymAxis() - point.getX() ); - else point.setY( 2*getSymAxis() - point.getY() ); - return point; + Point symPoint ( point ); + if (_state->isSymVertical()) symPoint.setX( 2*getSymAxis() - point.getX() ); + else symPoint.setY( 2*getSymAxis() - point.getY() ); + return symPoint; + } + + inline Interval DataSymmetric::getSymmetrical ( const Interval& interval ) const + { + DbU::Unit vmin = interval.getVMin(); + if ( (vmin != DbU::Min) and (vmin != DbU::Max) ) vmin = 2*getSymAxis() - vmin; + + DbU::Unit vmax = interval.getVMax(); + if ( (vmax != DbU::Max) and (vmax != DbU::Max) ) vmax = 2*getSymAxis() - vmax; + + return Interval( vmin, vmax ); } diff --git a/katana/src/katana/KatanaEngine.h b/katana/src/katana/KatanaEngine.h index 86368737..fa22d4a2 100644 --- a/katana/src/katana/KatanaEngine.h +++ b/katana/src/katana/KatanaEngine.h @@ -87,6 +87,8 @@ namespace Katana { RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const; Track* getTrackByPosition ( const Layer*, DbU::Unit axis, unsigned int mode=Constant::Nearest ) const; DataSymmetric* getDataSymmetric ( Net* ); + inline const std::map& + getSymmetrics () const; inline void printConfiguration () const; void printCompletion () const; void dumpMeasures ( std::ostream& ) const; @@ -161,6 +163,8 @@ namespace Katana { inline size_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); } inline size_t KatanaEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); } inline unsigned int KatanaEngine::getRipupLimit ( unsigned int type ) const { return _configuration->getRipupLimit(type); } + inline const std::map& + KatanaEngine::getSymmetrics () const { return _symmetrics; } inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; } inline size_t KatanaEngine::getRoutingPlanesSize () const { return _routingPlanes.size(); } inline void KatanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } diff --git a/katana/src/katana/NegociateWindow.h b/katana/src/katana/NegociateWindow.h index 3aa8eb18..cfb32d93 100644 --- a/katana/src/katana/NegociateWindow.h +++ b/katana/src/katana/NegociateWindow.h @@ -95,31 +95,32 @@ namespace Katana { , Packing = 2 }; public: - static NegociateWindow* create ( KatanaEngine* ); - void destroy (); - inline bool isInterrupted () const; - inline KatanaEngine* getKatanaEngine () const; - Hurricane::Cell* getCell () const; - inline const vector& getGCells () const; - inline RoutingEventQueue& getEventQueue (); - inline RoutingEventHistory& getEventHistory (); - inline RoutingEventLoop& getEventLoop (); - inline Stage getStage () const; - void setGCells ( const vector& ); - inline void setInterrupt ( bool ); - inline void setStage ( Stage ); - double computeWirelength (); - TrackElement* createTrackSegment ( AutoSegment*, unsigned int flags ); - void addRoutingEvent ( TrackElement*, unsigned int level ); - inline void rescheduleEvent ( RoutingEvent*, unsigned int level ); - void run ( unsigned int flags ); - void printStatistics () const; - void _createRouting ( Anabatic::GCell* ); - void _pack ( size_t& count, bool last ); - size_t _negociate (); - Hurricane::Record* _getRecord () const; - std::string _getString () const; - inline std::string _getTypeName () const; + static NegociateWindow* create ( KatanaEngine* ); + void destroy (); + inline bool isInterrupted () const; + inline KatanaEngine* getKatanaEngine () const; + Hurricane::Cell* getCell () const; + inline const vector& getGCells () const; + inline RoutingEventQueue& getEventQueue (); + inline RoutingEventHistory& getEventHistory (); + inline RoutingEventLoop& getEventLoop (); + inline Stage getStage () const; + void setGCells ( const vector& ); + inline void setInterrupt ( bool ); + inline void setStage ( Stage ); + double computeWirelength (); + TrackElement* createTrackSegment ( AutoSegment*, unsigned int flags ); + void addRoutingEvent ( TrackElement*, unsigned int level ); + inline void rescheduleEvent ( RoutingEvent*, unsigned int level ); + void run ( unsigned int flags ); + void printStatistics () const; + void _createRouting ( Anabatic::GCell* ); + void _associateSymmetrics (); + void _pack ( size_t& count, bool last ); + size_t _negociate (); + Hurricane::Record* _getRecord () const; + std::string _getString () const; + inline std::string _getTypeName () const; private: // Attributes. diff --git a/katana/src/katana/RoutingEvent.h b/katana/src/katana/RoutingEvent.h index a65553a5..16a2be13 100644 --- a/katana/src/katana/RoutingEvent.h +++ b/katana/src/katana/RoutingEvent.h @@ -152,6 +152,8 @@ namespace Katana { inline void setForcedToHint ( bool state = true ); void setAxisHint ( DbU::Unit ); void setAxisHintFromParent (); + inline void updateAxisHistory (); + inline void setInsertState ( unsigned int ); inline void incInsertState (); inline void resetInsertState (); inline void setEventLevel ( unsigned int ); @@ -162,8 +164,8 @@ namespace Katana { string _getString () const; string _getTypeName () const; private: - RoutingEvent ( TrackElement*, unsigned int mode ); - ~RoutingEvent (); + RoutingEvent ( TrackElement*, unsigned int mode ); + ~RoutingEvent (); protected: // Attributes. @@ -234,6 +236,8 @@ namespace Katana { 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::updateAxisHistory () { _axisHistory = _segment->getAxis(); } + inline void RoutingEvent::setInsertState ( unsigned int state ) { _insertState = state; } inline void RoutingEvent::incInsertState () { _insertState++; } inline void RoutingEvent::resetInsertState () { _insertState = 0; } inline void RoutingEvent::setEventLevel ( unsigned int level ) { _eventLevel = level; } diff --git a/katana/src/katana/SegmentFsm.h b/katana/src/katana/SegmentFsm.h index 01dd6eeb..5658d0c4 100644 --- a/katana/src/katana/SegmentFsm.h +++ b/katana/src/katana/SegmentFsm.h @@ -17,10 +17,12 @@ #ifndef KATANA_SEGMENT_FSM_H #define KATANA_SEGMENT_FSM_H +#include #include "katana/TrackCost.h" namespace Katana { + using std::array; class TrackElement; class DataNegociate; class RoutingEvent; @@ -105,79 +107,111 @@ namespace Katana { }; public: - SegmentFsm ( RoutingEvent* - , RoutingEventQueue& - , RoutingEventHistory& - ); - inline bool isFullBlocked () const; - inline RoutingEvent* getEvent () const; - inline RoutingEventQueue& getQueue () const; - inline RoutingEventHistory& getHistory () const; - inline unsigned int getState () const; - 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 vector& getActions (); - inline void setState ( unsigned int ); - void addAction ( TrackElement* - , unsigned int type - , DbU::Unit axisHint=0 - , unsigned int toState =0 - ); - void doActions (); - inline void clearActions (); - bool insertInTrack ( size_t ); - bool conflictSolveByHistory (); - bool conflictSolveByPlaceds (); - bool solveTerminalVsGlobal (); - bool desaturate (); - bool slackenTopology ( unsigned int flags=0 ); - bool solveFullBlockages (); - private: - bool _slackenStrap ( TrackElement*& - , DataNegociate*& - , unsigned int flags ); - bool _slackenLocal ( TrackElement*& - , DataNegociate*& - , unsigned int flags ); - bool _slackenGlobal ( TrackElement*& - , DataNegociate*& - , unsigned int flags ); - private: - RoutingEvent* _event; - RoutingEventQueue& _queue; - RoutingEventHistory& _history; - unsigned int _state; - DataNegociate* _data; - Interval _constraint; - Interval _optimal; - vector _costs; - vector _actions; - bool _fullBlocked; + SegmentFsm ( RoutingEvent* + , RoutingEventQueue& + , RoutingEventHistory& + ); + inline bool isFullBlocked () const; + inline bool isSymmetric () const; + inline RoutingEvent* getEvent () const; + inline RoutingEvent* getEvent1 () const; + inline RoutingEvent* getEvent2 () const; + inline RoutingEventQueue& getQueue () const; + inline RoutingEventHistory& getHistory () const; + inline TrackElement* getSegment1 () const; + inline TrackElement* getSegment2 () const; + inline unsigned int getState () const; + inline DataNegociate* getData (); + inline DataNegociate* getData1 (); + inline DataNegociate* getData2 (); + inline Interval& getConstraint (); + inline Interval& getOptimal (); + inline vector< array >& getCosts (); + inline TrackCost& getCost ( size_t ); + inline TrackCost& getCost1 ( size_t ); + inline TrackCost& getCost2 ( size_t ); + inline Track* getTrack ( size_t ); + inline size_t getBegin ( size_t ); + inline size_t getEnd ( size_t ); + inline vector& getActions (); + inline void setState ( unsigned int ); + void setDataState ( unsigned int ); + void addAction ( TrackElement* + , unsigned int type + , DbU::Unit axisHint=0 + , unsigned int toState =0 + ); + void doActions (); + inline void clearActions (); + inline SegmentFsm& useEvent1 (); + inline SegmentFsm& useEvent2 (); + void incRipupCount (); + bool insertInTrack ( size_t ); + void bindToTrack ( size_t ); + void moveToTrack ( size_t ); + void ripupPerpandiculars (); + bool canRipup ( unsigned int flags=0 ); + bool conflictSolveByHistory (); + bool conflictSolveByPlaceds (); + bool solveTerminalVsGlobal (); + bool desaturate (); + bool slackenTopology ( unsigned int flags=0 ); + bool solveFullBlockages (); + private: + bool _slackenStrap ( TrackElement*& + , DataNegociate*& + , unsigned int flags ); + bool _slackenLocal ( TrackElement*& + , DataNegociate*& + , unsigned int flags ); + bool _slackenGlobal ( TrackElement*& + , DataNegociate*& + , unsigned int flags ); + private: + RoutingEvent* _event1; + RoutingEvent* _event2; + RoutingEventQueue& _queue; + RoutingEventHistory& _history; + unsigned int _state; + DataNegociate* _data1; + DataNegociate* _data2; + Interval _constraint; + Interval _optimal; + vector< array > _costs; + vector _actions; + bool _fullBlocked; + bool _sameAxis; + bool _useEvent2; }; - inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } - inline RoutingEvent* SegmentFsm::getEvent () const { return _event; } - inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } - inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } - inline unsigned int SegmentFsm::getState () const { return _state; } - inline DataNegociate* SegmentFsm::getData () { return _data; } - inline Interval& SegmentFsm::getConstraint () { return _constraint; } - inline Interval& SegmentFsm::getOptimal () { return _optimal; } - inline vector& SegmentFsm::getCosts () { return _costs; } - inline TrackCost& SegmentFsm::getCost ( size_t i ) { return _costs[i]; } - inline Track* SegmentFsm::getTrack ( size_t i ) { return _costs[i].getTrack(); } - inline size_t SegmentFsm::getBegin ( size_t i ) { return _costs[i].getBegin(); } - inline size_t SegmentFsm::getEnd ( size_t i ) { return _costs[i].getEnd(); } - inline vector& SegmentFsm::getActions () { return _actions; } - inline void SegmentFsm::setState ( unsigned int state ) { _state = state; } - inline void SegmentFsm::clearActions () { _actions.clear(); } + inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } + inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } + inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } + inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } + inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } + inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } + inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } + inline unsigned int SegmentFsm::getState () const { return _state; } + inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } + inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } + inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } + inline DataNegociate* SegmentFsm::getData1 () { return _data1; } + inline DataNegociate* SegmentFsm::getData2 () { return _data2; } + inline Interval& SegmentFsm::getConstraint () { return _constraint; } + inline Interval& SegmentFsm::getOptimal () { return _optimal; } + inline vector< array >& SegmentFsm::getCosts () { return _costs; } + inline TrackCost& SegmentFsm::getCost ( size_t i ) { return _costs[i][0]; } + inline TrackCost& SegmentFsm::getCost1 ( size_t i ) { return _costs[i][0]; } + inline TrackCost& SegmentFsm::getCost2 ( size_t i ) { return _costs[i][1]; } + inline Track* SegmentFsm::getTrack ( size_t i ) { return (_useEvent2) ? _costs[i][1].getTrack() : _costs[i][0].getTrack(); } + inline size_t SegmentFsm::getBegin ( size_t i ) { return (_useEvent2) ? _costs[i][1].getBegin() : _costs[i][0].getBegin(); } + inline size_t SegmentFsm::getEnd ( size_t i ) { return (_useEvent2) ? _costs[i][1].getEnd () : _costs[i][0].getEnd (); } + inline vector& SegmentFsm::getActions () { return _actions; } + inline void SegmentFsm::setState ( unsigned int state ) { _state = state; } + inline void SegmentFsm::clearActions () { _actions.clear(); } + inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; } + inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; } } // Katana namespace. diff --git a/katana/src/katana/TrackCost.h b/katana/src/katana/TrackCost.h index c48108c0..ad489644 100644 --- a/katana/src/katana/TrackCost.h +++ b/katana/src/katana/TrackCost.h @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/TrackCost.h" | +// | C++ Header : "./katana/TrackCost.h" | // +-----------------------------------------------------------------+ @@ -61,9 +61,7 @@ namespace Katana { }; public: - TrackCost ( Track* track - , Net* net - ); + TrackCost ( Track* track ); TrackCost ( Track* track , const Interval& interval , size_t begin @@ -113,6 +111,7 @@ namespace Katana { inline void setLonguestOverlap ( DbU::Unit ); inline void mergeRipupCount ( int ); inline void mergeDataState ( unsigned int ); + void merge ( const TrackCost& ); void consolidate (); Record* _getRecord () const; string _getString () const; diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index e5b628a6..c8455bad 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -111,6 +111,7 @@ namespace Katana { inline bool isBlockage () const; inline bool isLocked () const; inline bool isRouted () const; + virtual bool hasSymmetric () const; inline bool hasSourceDogleg () const; inline bool hasTargetDogleg () const; inline bool canRipple () const; @@ -151,6 +152,7 @@ namespace Katana { virtual unsigned int getDoglegLevel () const; virtual TrackElement* getSourceDogleg (); virtual TrackElement* getTargetDogleg (); + virtual TrackElement* getSymmetric (); virtual TrackElements getPerpandiculars (); // Mutators. inline void setFlags ( unsigned int ); @@ -158,6 +160,7 @@ namespace Katana { inline void setRouted (); virtual void setTrack ( Track* ); inline void setIndex ( size_t ); + virtual void setSymmetric ( TrackElement* ); virtual void updateFreedomDegree (); virtual void setDoglegLevel ( unsigned int ); virtual void swapTrack ( TrackElement* ); diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index 033904d4..89ea3e53 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -72,6 +72,7 @@ namespace Katana { virtual bool isUTurn () const; virtual bool isUserDefined () const; // Predicates. + virtual bool hasSymmetric () const; virtual bool canDogleg (); virtual bool canDogleg ( Interval ); virtual bool canDogleg ( Anabatic::GCell*, unsigned int flags=0 ); @@ -100,10 +101,12 @@ namespace Katana { virtual size_t getGCells ( vector& ) const; virtual TrackElement* getSourceDogleg (); virtual TrackElement* getTargetDogleg (); + virtual TrackElement* getSymmetric (); virtual TrackElements getPerpandiculars (); virtual size_t getPerpandicularsBound ( set& ); // Mutators. virtual void setTrack ( Track* ); + virtual void setSymmetric ( TrackElement* ); virtual void updateFreedomDegree (); virtual void setDoglegLevel ( unsigned int ); virtual void swapTrack ( TrackElement* ); @@ -133,6 +136,7 @@ namespace Katana { // Attributes. static size_t _allocateds; AutoSegment* _base; + TrackSegment* _symmetric; unsigned long _freedomDegree; DbU::Unit _ppitch; DataNegociate* _data; From db8e51524feea38d64f611bced11f7c9be938233 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 3 May 2017 18:09:51 +0200 Subject: [PATCH 2/4] Deterministic destruction of Components. * Change: In Hurrican::Component::_preDestroy(), the cascaded destruction of slaves Components and subsequent ring merge and Rubber creation was using set<> sorted on pointer values. This was making the order of destruction of the slaves components non-deterministic. Now the sets are sorted according to their id (see Entity). * Change: In Hurricane::SharedProperty, the _ownerSet is now a vector<> instead of a set<>. This will slow the search process, but hopefully this is needed only during construction/destruction of a Property so the slow down shouldn't be too much. This has also an impact on Hurricane::Relation. --- anabatic/src/Edge.cpp | 6 +- crlcore/etc/common/display.conf | 2 +- crlcore/src/cyclop/Cyclop.cpp | 2 +- hurricane/src/hurricane/Component.cpp | 73 ++++++++----------- hurricane/src/hurricane/DBo.cpp | 6 +- hurricane/src/hurricane/Hook.cpp | 2 + hurricane/src/hurricane/Property.cpp | 42 +++++++++-- hurricane/src/hurricane/Relation.cpp | 3 +- .../src/hurricane/hurricane/IntrusiveSet.h | 9 +++ hurricane/src/hurricane/hurricane/Property.h | 3 +- 10 files changed, 92 insertions(+), 56 deletions(-) diff --git a/anabatic/src/Edge.cpp b/anabatic/src/Edge.cpp index 5323bf4a..d55439d9 100644 --- a/anabatic/src/Edge.cpp +++ b/anabatic/src/Edge.cpp @@ -88,9 +88,9 @@ namespace Anabatic { Edge* edge = new Edge ( source, target, flags ); edge->_postCreate(); - cdebug_log(110,1) << "Edge::create(): " << (void*)edge << ":" << edge << endl; - cdebug_log(110,0) << "source:" << (void*)source << ":" << edge->getSource() << endl; - cdebug_log(110,0) << "target:" << (void*)target << ":" << edge->getTarget() << endl; + cdebug_log(110,1) << "Edge::create(): " << /*(void*)edge << ":" <<*/ edge << endl; + cdebug_log(110,0) << "source:" << /*(void*)source << ":" <<*/ edge->getSource() << endl; + cdebug_log(110,0) << "target:" << /*(void*)target << ":" <<*/ edge->getTarget() << endl; cdebug_tabw(110,-1); return edge; } diff --git a/crlcore/etc/common/display.conf b/crlcore/etc/common/display.conf index 7209b8e4..24bf85fe 100644 --- a/crlcore/etc/common/display.conf +++ b/crlcore/etc/common/display.conf @@ -192,7 +192,7 @@ stylesTable = \ , (Drawing, 'gmetalv' , { 'color':'200,200,255', 'pattern':'light_antihash1.8', 'border':1 }) , (Drawing, 'gcut' , { 'color':'255,255,190', 'border':1 }) , (Drawing, 'Anabatic::Edge' , { 'color':'255,255,190', 'pattern':'0000000000000000', 'border':4, 'threshold':0.02*scale }) - , (Drawing, 'Anabatic::GCell', { 'color':'128,128,128', 'pattern':'0000000000000000', 'border':4, 'threshold':0.10*scale }) + , (Drawing, 'Anabatic::GCell', { 'color':'255,255,190', 'pattern':'0000000000000000', 'border':4, 'threshold':0.10*scale }) ) # ---------------------------------------------------------------------- diff --git a/crlcore/src/cyclop/Cyclop.cpp b/crlcore/src/cyclop/Cyclop.cpp index 3fdc92f5..70ee6adf 100644 --- a/crlcore/src/cyclop/Cyclop.cpp +++ b/crlcore/src/cyclop/Cyclop.cpp @@ -77,7 +77,7 @@ namespace CRL { _stressDisplayAction->setStatusTip ( tr("Intensive use of display redrawing") ); connect ( _stressDisplayAction, SIGNAL(triggered()), this, SLOT(stressDisplay()) ); - debugMenu->addAction ( _stressDisplayAction ); + //debugMenu->addAction ( _stressDisplayAction ); getCellWidget()->addDrawExtensionGo ( DemoGo::staticGetName() , DemoGo::initDrawDemoGo diff --git a/hurricane/src/hurricane/Component.cpp b/hurricane/src/hurricane/Component.cpp index cdd355c5..e93aa66c 100644 --- a/hurricane/src/hurricane/Component.cpp +++ b/hurricane/src/hurricane/Component.cpp @@ -408,58 +408,50 @@ void Component::_postCreate() void Component::_preDestroy() // ************************* { - cdebug_log(18,1) << "entering Component::_Predestroy: " << this << endl; + cdebug_log(18,1) << "entering Component::_preDestroy: " << this << endl; clearProperties(); - set componentSet; - getSlaveComponents().fill(componentSet); + set components; + getSlaveComponents().fill( components ); + components.insert( this ); - set masterHookSet; - componentSet.insert(this); - for_each_component(component, getCollection(componentSet)) { - component->unmaterialize(); - for_each_hook(hook, component->getHooks()) { - for_each_hook(hook, hook->getHooks()) { - if (hook->isMaster() && (componentSet.find(hook->getComponent()) == componentSet.end())) - masterHookSet.insert(hook); - end_for; - } - if (!hook->isMaster()) hook->detach(); - end_for; + vector masterHooks; + + for ( Component* component : components ) { + component->unmaterialize(); + for ( Hook* chook : component->getHooks() ) { + for ( Hook* shook : chook->getHooks() ) { + if (shook->isMaster() and (components.find(shook->getComponent()) == components.end()) ) + masterHooks.push_back( shook ); } - end_for; + if (not chook->isMaster()) chook->detach(); + } } - componentSet.erase(this); - for_each_component(component, getCollection(componentSet)) { - component->destroy(); - end_for; - } + components.erase( this ); + for ( Component* component : components ) component->destroy(); - set rubberSet; - set mainMasterHookSet; - for_each_hook(hook, getCollection(masterHookSet)) { - Rubber* rubber = hook->getComponent()->getRubber(); - if (!rubber) - mainMasterHookSet.insert(hook); - else { - if (rubberSet.find(rubber) == rubberSet.end()) { - rubberSet.insert(rubber); - mainMasterHookSet.insert(hook); - } + set rubbers; + vector mainMasterHooks; + + for ( Hook* mhook : masterHooks ) { + Rubber* rubber = mhook->getComponent()->getRubber(); + if (not rubber) + mainMasterHooks.push_back( mhook ); + else { + if (rubbers.find(rubber) == rubbers.end()) { + rubbers.insert( rubber ); + mainMasterHooks.push_back( mhook ); } - end_for; + } } + Hook* masterHook = NULL; - for_each_hook(hook, getCollection(mainMasterHookSet)) { - if (!masterHook) - masterHook = hook; - else - hook->merge(masterHook); - end_for; + for ( Hook* hook : mainMasterHooks ) { + if (not masterHook) masterHook = hook; + else hook->merge( masterHook ); } - /**/ _bodyHook.detach(); @@ -467,7 +459,6 @@ void Component::_preDestroy() if (_net) _net->_getComponentSet()._remove(this); - cdebug_log(18,0) << "exiting Component::_Predestroy:" << endl; cdebug_tabw(18,-1); } diff --git a/hurricane/src/hurricane/DBo.cpp b/hurricane/src/hurricane/DBo.cpp index 88045cf0..15c02d8a 100644 --- a/hurricane/src/hurricane/DBo.cpp +++ b/hurricane/src/hurricane/DBo.cpp @@ -53,7 +53,9 @@ namespace Hurricane { void DBo::_postCreate () - { } + { + cdebug_log(0,0) << "DBo::_postCreate() " << this << endl; + } void DBo::_preDestroy () @@ -64,7 +66,9 @@ namespace Hurricane { void DBo::destroy () { + cdebug_log(0,1) << "DBo::destroy() " << this << endl; _preDestroy(); + cdebug_tabw(0,-1); delete this; } diff --git a/hurricane/src/hurricane/Hook.cpp b/hurricane/src/hurricane/Hook.cpp index 5c6d75a7..79fd5e22 100644 --- a/hurricane/src/hurricane/Hook.cpp +++ b/hurricane/src/hurricane/Hook.cpp @@ -362,6 +362,8 @@ Hook* Hook::merge(Hook* hook) if (hook == this) throw Error("Can't merge : itself"); + cdebug_log(0,0) << "Hook::merge() hook:" << hook->getComponent() << endl; + Hook* masterHook = hook->getPreviousMasterHook(); Hook* nextHook = masterHook->_nextHook; masterHook->_nextHook = _nextHook; diff --git a/hurricane/src/hurricane/Property.cpp b/hurricane/src/hurricane/Property.cpp index c29667db..0e6c20b2 100644 --- a/hurricane/src/hurricane/Property.cpp +++ b/hurricane/src/hurricane/Property.cpp @@ -226,25 +226,53 @@ namespace Hurricane { void SharedProperty::_preDestroy () { - Property::_preDestroy(); + for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { + _ownerSet[i]->_onDestroyed(this); + _ownerSet[i] = NULL; + } + _ownerSet.clear(); - while (!_ownerSet.empty()) { - DBo* owner = *_ownerSet.begin(); - _ownerSet.erase(owner); - owner->_onDestroyed(this); + // while (!_ownerSet.empty()) { + // DBo* owner = *_ownerSet.begin(); + // _ownerSet.erase(owner); + // owner->_onDestroyed(this); + // } + + Property::_preDestroy(); + } + + + void SharedProperty::_erase ( DBo* owner ) + { + for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { + if (_ownerSet[i] == owner) { + std::swap( _ownerSet[i], _ownerSet[_ownerSet.size()-1] ); + _ownerSet.pop_back(); + } } } void SharedProperty::onCapturedBy ( DBo* owner ) { - _ownerSet.insert(owner); + for ( DBo* dbo : _ownerSet ) { + if (dbo == owner) return; + } + _ownerSet.push_back( owner ); + + //_ownerSet.insert(owner); } void SharedProperty::onReleasedBy ( DBo* owner ) { - _ownerSet.erase(owner); + for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) { + if (_ownerSet[i] == owner) { + std::swap( _ownerSet[i], _ownerSet[_ownerSet.size()-1] ); + _ownerSet.pop_back(); + } + } + //_ownerSet.erase(owner); if (_ownerSet.empty()) onNotOwned(); } diff --git a/hurricane/src/hurricane/Relation.cpp b/hurricane/src/hurricane/Relation.cpp index 3a34cc07..d97f1744 100644 --- a/hurricane/src/hurricane/Relation.cpp +++ b/hurricane/src/hurricane/Relation.cpp @@ -99,7 +99,8 @@ DBos Relation::getSlaveOwners() const void Relation::onReleasedBy(DBo* owner) // ************************************ { - _getOwnerSet().erase(owner); + _erase( owner ); +//_getOwnerSet().erase(owner); if (owner == _masterOwner) destroy(); } diff --git a/hurricane/src/hurricane/hurricane/IntrusiveSet.h b/hurricane/src/hurricane/hurricane/IntrusiveSet.h index 44faeb35..48106d88 100644 --- a/hurricane/src/hurricane/hurricane/IntrusiveSet.h +++ b/hurricane/src/hurricane/hurricane/IntrusiveSet.h @@ -433,14 +433,23 @@ template class IntrusiveSet { _length = newLength; _array = new Element*[_length]; memset(_array, 0, _length * sizeof(Element*)); + cdebug_log(0,0) << "IntrusiveSet::_resize() " << oldLength << " -> " << newLength << endl; + for (unsigned index = 0; index < oldLength; index++) { Element* element = oldArray[index]; + if (not element) + cdebug_log(0,0) << "| bucket:" << setw(4) << index << " empty" << endl; + while (element) { Element* nextElement = _getNextElement(element); unsigned newIndex = (_getHashValue(element) / 8) % _length; _setNextElement(element, _array[newIndex]); _array[newIndex] = element; element = nextElement; + + cdebug_log(0,0) << "| bucket:" << setw(4) << index + << " -> " << setw(4) << newIndex + << " + " << element << endl; } } delete[] oldArray; diff --git a/hurricane/src/hurricane/hurricane/Property.h b/hurricane/src/hurricane/hurricane/Property.h index da90d18a..a0e2d7a2 100644 --- a/hurricane/src/hurricane/hurricane/Property.h +++ b/hurricane/src/hurricane/hurricane/Property.h @@ -396,7 +396,7 @@ namespace Hurricane { unsigned int _count; }; public: - typedef set DBoSet; + typedef vector DBoSet; typedef map OrphanedMap; public: static const OrphanedMap& getOrphaneds (); @@ -411,6 +411,7 @@ namespace Hurricane { virtual void onCapturedBy ( DBo* owner ); virtual void onReleasedBy ( DBo* owner ); virtual void onNotOwned (); + void _erase ( DBo* owner ); inline DBoSet& _getOwnerSet (); virtual string _getString () const; virtual Record* _getRecord () const; From 6c229ce0762113fb321fbd04234925a33dc683a2 Mon Sep 17 00:00:00 2001 From: Roselyne Chotin-Avot Date: Fri, 5 May 2017 12:01:26 +0200 Subject: [PATCH 3/4] =?UTF-8?q?Remove=20=E2=80=98-=E2=80=98=20=20from=20zs?= =?UTF-8?q?h=20shell=20on=20MacOS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bootstrap/coriolisEnv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/coriolisEnv.py b/bootstrap/coriolisEnv.py index 34940328..e359cf8d 100755 --- a/bootstrap/coriolisEnv.py +++ b/bootstrap/coriolisEnv.py @@ -147,7 +147,7 @@ def guessShell (): #if os.environ.has_key('SHELL'): return os.environ['SHELL'] psCommand = subprocess.Popen ( ['ps', '-p', str(os.getppid()) ], stdout=subprocess.PIPE ) - shell = psCommand.stdout.readlines()[1][:-1].split()[-1] + shell = psCommand.stdout.readlines()[1][:-1].split()[-1].lstrip('-') whichCommand = subprocess.Popen ( ['which', shell ], stdout=subprocess.PIPE ) shellPath = whichCommand.stdout.readlines()[0][:-1] From f1b2035cb09f0ec76410e4ef13f9fae99e13ee06 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 9 May 2017 18:33:55 +0200 Subject: [PATCH 4/4] Support for profiling the priority of events in Kite & Katana. * New: In Katana::Configuration, added "katana.profileEventCosts" to triggers the event's profiling. * New: In Katana::NegociateWindow::_negociate(), save a profiling trace of all the events and their priority, separated by metal, for later analysis (see doChip.py in alliance-check-toolkit). * New: In Katana::RoutingEvent::Key::Compare(), start implementing new segment freedom degree functions. * Change: In Hurricane::Net::_getString(), put a more complete information about the Net instead of just only it's name. * Bug: In Katana, reorder the various stages so that they are executed in the exact same sequence as in "doChip.py" so now routing in graphic mode and text mode gives exactly the same results. * Bug: In Katana::PyKatanaEngine, runGlobalRouter do not take any argument. --- anabatic/src/Configuration.cpp | 2 ++ hurricane/src/hurricane/Net.cpp | 14 +++++++-- .../src/hurricane/hurricane/DebugSession.h | 8 ++--- katana/src/Configuration.cpp | 12 +++++--- katana/src/GlobalRoute.cpp | 3 +- katana/src/GraphicKatanaEngine.cpp | 2 +- katana/src/NegociateWindow.cpp | 24 ++++++++++++++- katana/src/PyKatanaEngine.cpp | 20 +++++-------- katana/src/RoutingEvent.cpp | 30 ++++++++++++------- katana/src/SegmentFsm.cpp | 4 +++ katana/src/Track.cpp | 7 ++--- katana/src/katana/Configuration.h | 7 ++++- katana/src/katana/KatanaEngine.h | 2 ++ kite/src/Configuration.cpp | 10 ++++--- kite/src/NegociateWindow.cpp | 22 +++++++++++++- kite/src/kite/Configuration.h | 5 ++++ kite/src/kite/KiteEngine.h | 2 ++ 17 files changed, 126 insertions(+), 48 deletions(-) diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 843e6922..b6861a1b 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -328,6 +328,8 @@ namespace Anabatic { void Configuration::print ( Cell* cell ) const { + if (not cmess1.enabled()) return; + string topLayerName = "UNKOWN"; const Layer* topLayer = _rg->getRoutingLayer( _allowedDepth ); if (topLayer) diff --git a/hurricane/src/hurricane/Net.cpp b/hurricane/src/hurricane/Net.cpp index 30f682a0..d4861668 100644 --- a/hurricane/src/hurricane/Net.cpp +++ b/hurricane/src/hurricane/Net.cpp @@ -748,9 +748,17 @@ void Net::_preDestroy() string Net::_getString() const // *************************** { - string s = Inherit::_getString(); - s.insert(s.length() - 1, " " + getString(_name)); - return s; + string bs = Inherit::_getString(); + string ds = "\"" + getString(_name) + "\" "; + ds += ((_isExternal ) ? "e" : "-"); + ds += ((_isGlobal ) ? "g" : "-"); + ds += ((_isAutomatic) ? "a" : "-"); + ds += " "; + ds += getString(_type ) + " "; + ds += getString(_direction); + + bs.insert( bs.length() - 1, " " + ds ); + return bs; } Record* Net::_getRecord() const diff --git a/hurricane/src/hurricane/hurricane/DebugSession.h b/hurricane/src/hurricane/hurricane/DebugSession.h index 2b87579e..a01d893b 100644 --- a/hurricane/src/hurricane/hurricane/DebugSession.h +++ b/hurricane/src/hurricane/hurricane/DebugSession.h @@ -126,12 +126,12 @@ namespace Hurricane { DebugSession* DebugSession::get () { return _singleton; } bool DebugSession::isTraced ( const void* symbol ) { return _singleton->_isTraced(symbol); } void DebugSession::addToTrace ( const void* symbol ) { _singleton->_addToTrace(symbol); } - void DebugSession::addToTrace ( const Net* net ) { _singleton->_addToTrace ( net ); } + void DebugSession::addToTrace ( const Net* net ) { _singleton->_addToTrace(net); } void DebugSession::addToTrace ( const Cell* cell - , const Name& name ) { _singleton->_addToTrace ( cell, name ); } + , const Name& name ) { _singleton->_addToTrace( cell, name ); } bool DebugSession::_isTraced ( const void* symbol ) const { return _symbols.find(symbol) != _symbols.end(); } - void DebugSession::_addToTrace ( const void* symbol ) { _symbols.insert ( symbol ); } - void DebugSession::_addToTrace ( const Net* net ) { _addToTrace ( static_cast(net) ); } + void DebugSession::_addToTrace ( const void* symbol ) { _symbols.insert( symbol ); } + void DebugSession::_addToTrace ( const Net* net ) { _addToTrace( static_cast(net) ); } diff --git a/katana/src/Configuration.cpp b/katana/src/Configuration.cpp index d3537fe0..c42f1bf4 100644 --- a/katana/src/Configuration.cpp +++ b/katana/src/Configuration.cpp @@ -40,12 +40,13 @@ namespace Katana { Configuration::Configuration () : Anabatic::Configuration() , _postEventCb () - , _hTracksReservedLocal(Cfg::getParamInt("katana.hTracksReservedLocal", 3)->asInt()) - , _vTracksReservedLocal(Cfg::getParamInt("katana.vTracksReservedLocal", 3)->asInt()) + , _hTracksReservedLocal(Cfg::getParamInt ("katana.hTracksReservedLocal", 3)->asInt()) + , _vTracksReservedLocal(Cfg::getParamInt ("katana.vTracksReservedLocal", 3)->asInt()) , _ripupLimits () - , _ripupCost (Cfg::getParamInt("katana.ripupCost" , 3)->asInt()) - , _eventsLimit (Cfg::getParamInt("katana.eventsLimit" ,4000000)->asInt()) + , _ripupCost (Cfg::getParamInt ("katana.ripupCost" , 3)->asInt()) + , _eventsLimit (Cfg::getParamInt ("katana.eventsLimit" ,4000000)->asInt()) , _flags (0) + , _profileEventCosts (Cfg::getParamBool("katana.profileEventCosts" ,false )->asBool()) { _ripupLimits[StrapRipupLimit] = Cfg::getParamInt("katana.strapRipupLimit" ,16)->asInt(); _ripupLimits[LocalRipupLimit] = Cfg::getParamInt("katana.localRipupLimit" , 7)->asInt(); @@ -81,6 +82,7 @@ namespace Katana { , _ripupLimits () , _ripupCost (other._ripupCost) , _eventsLimit (other._eventsLimit) + , _profileEventCosts (other._profileEventCosts) { _ripupLimits[StrapRipupLimit] = other._ripupLimits[StrapRipupLimit]; _ripupLimits[LocalRipupLimit] = other._ripupLimits[LocalRipupLimit]; @@ -142,6 +144,8 @@ namespace Katana { void Configuration::print ( Cell* cell ) const { + if (not cmess1.enabled()) return; + cout << " o Configuration of ToolEngine for Cell <" << cell->getName() << ">" << endl; cout << Dots::asUInt (" - Global router H reserved local" ,_hTracksReservedLocal) << endl; cout << Dots::asUInt (" - Global router V reserved local" ,_vTracksReservedLocal) << endl; diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index a5758363..169b03d1 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -25,6 +25,7 @@ namespace { using std::cerr; using std::endl; using std::setw; + using std::setfill; using std::left; using std::right; using Hurricane::DbU; @@ -162,7 +163,7 @@ namespace Katana { size_t iteration = 0; size_t netCount = 0; do { - cmess2 << " [" << setw(3) << iteration << "] nets:"; + cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:"; netCount = 0; for ( NetData* netData : getNetOrdering() ) { diff --git a/katana/src/GraphicKatanaEngine.cpp b/katana/src/GraphicKatanaEngine.cpp index a6b03a0b..6070257a 100644 --- a/katana/src/GraphicKatanaEngine.cpp +++ b/katana/src/GraphicKatanaEngine.cpp @@ -194,8 +194,8 @@ namespace Katana { katana = KatanaEngine::create( cell ); katana->setPostEventCb( boost::bind(&GraphicKatanaEngine::postEvent,this) ); katana->setViewer( _viewer ); + katana->printConfiguration(); katana->digitalInit(); - if (cmess1.enabled()) katana->printConfiguration(); } else cerr << Warning( "%s already has a Katana engine.", getString(cell).c_str() ) << endl; diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 3b8cc2a6..eeca94a9 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include "hurricane/Warning.h" #include "hurricane/Bug.h" @@ -137,6 +138,7 @@ namespace { namespace Katana { + using std::ofstream; using std::cerr; using std::endl; using std::setw; @@ -425,7 +427,11 @@ namespace Katana { cmess1 << " o Negociation Stage." << endl; - unsigned long limit = _katana->getEventsLimit(); + unsigned long limit = _katana->getEventsLimit(); + bool profiling = _katana->profileEventCosts(); + ofstream ofprofile; + + if (profiling) ofprofile.open( "katana.profile.txt" ); _eventHistory.clear(); _eventQueue.load( _segments ); @@ -453,6 +459,21 @@ namespace Katana { cmess2.flush(); } + if (ofprofile.is_open()) { + size_t depth = _katana->getConfiguration()->getLayerDepth( event->getSegment()->getLayer() ); + if (depth < 6) { + ofprofile << setw(10) << right << count << " "; + for ( size_t i=0 ; i<6 ; ++i ) { + if (i == depth) + ofprofile << setw(10) << right << setprecision(2) << event->getPriority () << " "; + else + ofprofile << setw(10) << right << setprecision(2) << 0.0 << " "; + } + + ofprofile << setw( 2) << right << event->getEventLevel() << endl; + } + } + event->process( _eventQueue, _eventHistory, _eventLoop ); count++; @@ -519,6 +540,7 @@ namespace Katana { cerr << Bug( "%d events remains after clear.", RoutingEvent::getAllocateds() ) << endl; } + if (ofprofile.is_open()) ofprofile.close(); _statistics.setEventsCount( eventsCount ); cdebug_tabw(159,-1); diff --git a/katana/src/PyKatanaEngine.cpp b/katana/src/PyKatanaEngine.cpp index 8222a1da..d9ea2a7c 100644 --- a/katana/src/PyKatanaEngine.cpp +++ b/katana/src/PyKatanaEngine.cpp @@ -167,25 +167,19 @@ extern "C" { } - PyObject* PyKatanaEngine_runGlobalRouter ( PyKatanaEngine* self, PyObject* args ) + PyObject* PyKatanaEngine_runGlobalRouter ( PyKatanaEngine* self ) { cdebug_log(40,0) << "PyKatanaEngine_runGlobalRouter()" << endl; HTRY METHOD_HEAD("KatanaEngine.runGlobalRouter()") - unsigned int flags = 0; - if (PyArg_ParseTuple(args,"I:KatanaEngine.runGlobalRouter", &flags)) { - if (katana->getViewer()) { - if (ExceptionWidget::catchAllWrapper( std::bind(&KatanaEngine::runGlobalRouter,katana) )) { - PyErr_SetString( HurricaneError, "KatanaEngine::runGlobalrouter() has thrown an exception (C++)." ); - return NULL; - } - } else { - katana->runGlobalRouter(); + if (katana->getViewer()) { + if (ExceptionWidget::catchAllWrapper( std::bind(&KatanaEngine::runGlobalRouter,katana) )) { + PyErr_SetString( HurricaneError, "KatanaEngine::runGlobalrouter() has thrown an exception (C++)." ); + return NULL; } } else { - PyErr_SetString(ConstructorError, "KatanaEngine.runGlobalRouter(): Invalid number/bad type of parameter."); - return NULL; + katana->runGlobalRouter(); } HCATCH @@ -311,7 +305,7 @@ extern "C" { , "Display on the console the configuration of Katana." } , { "getToolSuccess" , (PyCFunction)PyKatanaEngine_getToolSuccess , METH_NOARGS , "Returns True if the detailed routing has been successful." } - , { "runGlobalRouter" , (PyCFunction)PyKatanaEngine_runGlobalRouter , METH_VARARGS + , { "runGlobalRouter" , (PyCFunction)PyKatanaEngine_runGlobalRouter , METH_NOARGS , "Run the global router (Katana)." } , { "loadGlobalRouting" , (PyCFunction)PyKatanaEngine_loadGlobalRouting , METH_VARARGS , "Load global routing into the detailed router." } diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index f07a4d8e..f161e3ca 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -79,11 +80,11 @@ namespace Katana { if (lhs._eventLevel < rhs._eventLevel) return true; // Process all M2 (terminal access) before any others. - if ((lhs._layerDepth == 1) and (rhs._layerDepth != 1)) return false; - if ((lhs._layerDepth != 1) and (rhs._layerDepth == 1)) return true; + //if ((lhs._layerDepth == 1) and (rhs._layerDepth != 1)) return false; + //if ((lhs._layerDepth != 1) and (rhs._layerDepth == 1)) return true; - if (lhs._priority > rhs._priority) return false; - if (lhs._priority < rhs._priority) return true; + if (lhs._priority > rhs._priority) return true; + if (lhs._priority < rhs._priority) return false; if (lhs._length > rhs._length) return false; if (lhs._length < rhs._length) return true; @@ -401,11 +402,11 @@ namespace Katana { cdebug_tabw(159,1); cdebug_log(159,0) << "State: *before* " - << DataNegociate::getStateString(_segment->getDataNegociate()) - << " ripup:" << _segment->getDataNegociate()->getRipupCount() - << endl; + << DataNegociate::getStateString(_segment->getDataNegociate()) + << " ripup:" << _segment->getDataNegociate()->getRipupCount() + << endl; cdebug_log(159,0) << "Level: " << getEventLevel() - << ", area: " << _segment->getFreedomDegree() << endl; + << ", area: " << _segment->getFreedomDegree() << endl; //_preCheck( _segment ); _eventLevel = 0; @@ -648,10 +649,17 @@ namespace Katana { _overConstrained = _segment->base()->getAutoSource()->isTerminal() and _segment->base()->getAutoTarget()->isTerminal(); } + + double length = DbU::toLambda(_segment->getLength()); + + // if (length > 200.0) length = 200.0 - std::log(length)*20.0; + // if (length < 0.0) length = 0.0; - _priority - = (DbU::toLambda(_segment->getLength()) + 1.0) - * (DbU::toLambda(_segment->base()->getSlack()) + 1.0); + _priority = (length + 1.0) * (DbU::toLambda(_segment->base()->getSlack()) + 1.0); + + // if (_priority > 10000.0) cerr << "_priority:" << _priority + // << " length:" << DbU::toLambda(_segment->getLength()) + // << " slack:" << DbU::toLambda(_segment->base()->getSlack()) << endl; cdebug_log(159,0) << _segment << " has " << (int)_tracksNb << " choices " << perpandicular << endl; cdebug_tabw(159,-1); diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index 8748fe49..73abf1e7 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -503,8 +503,10 @@ namespace Katana { _event2 = _data2->getRoutingEvent(); _event2->setTracksFree( 0 ); + cdebug_log(159,1) << "Coupled:" << _event2 << endl; _data2->update(); _event2->revalidate(); + cdebug_tabw(159,-1); _sameAxis = (segment1->isVertical() xor symData->isSymVertical()); } @@ -639,6 +641,8 @@ namespace Katana { cdebug_log(159,0) << "TrackCost::Compare() - DiscardGlobals" << endl; } + // FOR ANALOG ONLY. + //flags |= TrackCost::IgnoreSharedLength; sort( _costs.begin(), _costs.end(), CompareCostArray(flags) ); size_t i=0; diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 95589186..7424c1eb 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -172,10 +172,8 @@ namespace Katana { TrackElement* Track::getPrevious ( size_t& index, Net* net ) const { for ( index-- ; index != npos ; index-- ) { - if (cdebug.enabled()) { - cerr << tab << index << ":"; cerr.flush(); - cerr << _segments[index] << endl; - } + cdebug_log(140,0) << index << ":" << _segments[index] << endl; + if (_segments[index]->getNet() == net) continue; return _segments[index]; } @@ -437,6 +435,7 @@ namespace Katana { } } } + cdebug_tabw(155,-1); return Interval( minFree, getMaximalPosition(end,state) ); diff --git a/katana/src/katana/Configuration.h b/katana/src/katana/Configuration.h index c76dfa5e..2f6c0bc5 100644 --- a/katana/src/katana/Configuration.h +++ b/katana/src/katana/Configuration.h @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/Configuration.h" | +// | C++ Header : "./katana/Configuration.h" | // +-----------------------------------------------------------------+ @@ -60,6 +60,7 @@ namespace Katana { ~Configuration (); // Decorateds. inline bool useClockTree () const; + inline bool profileEventCosts () const; // Methods. inline Anabatic::Configuration* base (); inline const Anabatic::Configuration* base () const; @@ -77,6 +78,7 @@ namespace Katana { void setVTracksReservedLocal ( size_t ); inline void setFlags ( unsigned int ); inline void unsetFlags ( unsigned int ); + inline void setProfileEventCosts ( bool ); virtual void print ( Cell* ) const; virtual Record* _getRecord () const; virtual string _getString () const; @@ -90,6 +92,7 @@ namespace Katana { unsigned int _ripupCost; unsigned long _eventsLimit; unsigned int _flags; + bool _profileEventCosts; private: Configuration ( const Configuration& other ); Configuration& operator= ( const Configuration& ); @@ -108,8 +111,10 @@ namespace Katana { inline void Configuration::setPostEventCb ( PostEventCb_t cb ) { _postEventCb = cb; } inline void Configuration::setEventsLimit ( unsigned long limit ) { _eventsLimit = limit; } inline bool Configuration::useClockTree () const { return _flags & UseClockTree; } + inline bool Configuration::profileEventCosts () const { return _profileEventCosts; } inline void Configuration::setFlags ( unsigned int flags ) { _flags |= flags; } inline void Configuration::unsetFlags ( unsigned int flags ) { _flags &= ~flags; } + inline void Configuration::setProfileEventCosts ( bool state ) { _profileEventCosts = state; } diff --git a/katana/src/katana/KatanaEngine.h b/katana/src/katana/KatanaEngine.h index fa22d4a2..2b6694a0 100644 --- a/katana/src/katana/KatanaEngine.h +++ b/katana/src/katana/KatanaEngine.h @@ -78,6 +78,7 @@ namespace Katana { inline unsigned int getRipupCost () const; inline size_t getHTracksReservedLocal () const; inline size_t getVTracksReservedLocal () const; + inline bool profileEventCosts () const; virtual const Name& getName () const; inline Configuration::PostEventCb_t& getPostEventCb (); @@ -163,6 +164,7 @@ namespace Katana { inline size_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); } inline size_t KatanaEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); } inline unsigned int KatanaEngine::getRipupLimit ( unsigned int type ) const { return _configuration->getRipupLimit(type); } + inline bool KatanaEngine::profileEventCosts () const { return _configuration->profileEventCosts(); } inline const std::map& KatanaEngine::getSymmetrics () const { return _symmetrics; } inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; } diff --git a/kite/src/Configuration.cpp b/kite/src/Configuration.cpp index 9c2f28d9..bf708b57 100644 --- a/kite/src/Configuration.cpp +++ b/kite/src/Configuration.cpp @@ -41,12 +41,13 @@ namespace Kite { : Katabatic::Configuration() , _base (base) , _postEventCb () - , _hTracksReservedLocal(Cfg::getParamInt("kite.hTracksReservedLocal", 3)->asInt()) - , _vTracksReservedLocal(Cfg::getParamInt("kite.vTracksReservedLocal", 3)->asInt()) + , _hTracksReservedLocal(Cfg::getParamInt ("kite.hTracksReservedLocal", 3)->asInt()) + , _vTracksReservedLocal(Cfg::getParamInt ("kite.vTracksReservedLocal", 3)->asInt()) , _ripupLimits () - , _ripupCost (Cfg::getParamInt("kite.ripupCost" , 3)->asInt()) - , _eventsLimit (Cfg::getParamInt("kite.eventsLimit" ,4000000)->asInt()) + , _ripupCost (Cfg::getParamInt ("kite.ripupCost" , 3)->asInt()) + , _eventsLimit (Cfg::getParamInt ("kite.eventsLimit" ,4000000)->asInt()) , _flags (0) + , _profileEventCosts (Cfg::getParamBool("kite.profileEventCosts" ,false )->asBool()) { _ripupLimits[StrapRipupLimit] = Cfg::getParamInt("kite.strapRipupLimit" ,16)->asInt(); _ripupLimits[LocalRipupLimit] = Cfg::getParamInt("kite.localRipupLimit" , 7)->asInt(); @@ -83,6 +84,7 @@ namespace Kite { , _ripupLimits () , _ripupCost (other._ripupCost) , _eventsLimit (other._eventsLimit) + , _profileEventCosts (other._profileEventCosts) { if ( _base == NULL ) _base = other._base->clone(); diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index 1a8d882c..7cbb3f8e 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -429,7 +429,11 @@ namespace Kite { cmess1 << " o Negociation Stage." << endl; - unsigned long limit = _kite->getEventsLimit(); + unsigned long limit = _kite->getEventsLimit(); + bool profiling = _kite->profileEventCosts(); + ofstream ofprofile; + + if (profiling) ofprofile.open( "kite.profile.txt" ); _eventHistory.clear(); _eventQueue.load( _segments ); @@ -457,6 +461,21 @@ namespace Kite { cmess2.flush(); } + if (ofprofile.is_open()) { + size_t depth = _kite->getConfiguration()->getLayerDepth( event->getSegment()->getLayer() ); + if (depth < 6) { + ofprofile << setw(10) << right << count << " "; + for ( size_t i=0 ; i<6 ; ++i ) { + if (i == depth) + ofprofile << setw(10) << right << setprecision(2) << event->getPriority () << " "; + else + ofprofile << setw(10) << right << setprecision(2) << 0.0 << " "; + } + + ofprofile << setw( 2) << right << event->getEventLevel() << endl; + } + } + event->process( _eventQueue, _eventHistory, _eventLoop ); count++; @@ -523,6 +542,7 @@ namespace Kite { cerr << Bug( "%d events remains after clear.", RoutingEvent::getAllocateds() ) << endl; } + if (ofprofile.is_open()) ofprofile.close(); _statistics.setEventsCount( eventsCount ); cdebug_tabw(159,-1); diff --git a/kite/src/kite/Configuration.h b/kite/src/kite/Configuration.h index b8e0a343..0a21a7e0 100644 --- a/kite/src/kite/Configuration.h +++ b/kite/src/kite/Configuration.h @@ -60,6 +60,7 @@ namespace Kite { virtual bool isGMetal ( const Layer* ) const; virtual bool isGContact ( const Layer* ) const; inline bool useClockTree () const; + inline bool profileEventCosts () const; virtual size_t getDepth () const; virtual size_t getAllowedDepth () const; virtual DbU::Unit getSliceHeight () const; @@ -89,6 +90,7 @@ namespace Kite { virtual void setSaturateRatio ( float ); virtual void setSaturateRp ( size_t ); virtual void setGlobalThreshold ( DbU::Unit ); + inline void setProfileEventCosts ( bool ); virtual void print ( Cell* ) const; // Methods. inline Katabatic::Configuration* base (); @@ -119,6 +121,7 @@ namespace Kite { unsigned int _ripupCost; unsigned long _eventsLimit; unsigned int _flags; + bool _profileEventCosts; private: Configuration ( const Configuration& other, Katabatic::Configuration* base=NULL ); Configuration& operator= ( const Configuration& ); @@ -136,8 +139,10 @@ namespace Kite { inline void Configuration::setPostEventCb ( PostEventCb_t cb ) { _postEventCb = cb; } inline void Configuration::setEventsLimit ( unsigned long limit ) { _eventsLimit = limit; } inline bool Configuration::useClockTree () const { return _flags & UseClockTree; } + inline bool Configuration::profileEventCosts () const { return _profileEventCosts; } inline void Configuration::setFlags ( unsigned int flags ) { _flags |= flags; } inline void Configuration::unsetFlags ( unsigned int flags ) { _flags &= ~flags; } + inline void Configuration::setProfileEventCosts ( bool state ) { _profileEventCosts = state; } diff --git a/kite/src/kite/KiteEngine.h b/kite/src/kite/KiteEngine.h index eba26afd..737ba4b3 100644 --- a/kite/src/kite/KiteEngine.h +++ b/kite/src/kite/KiteEngine.h @@ -78,6 +78,7 @@ namespace Kite { inline unsigned int getRipupCost () const; inline size_t getHTracksReservedLocal () const; inline size_t getVTracksReservedLocal () const; + inline bool profileEventCosts () const; virtual const Name& getName () const; inline Configuration::PostEventCb_t& getPostEventCb (); @@ -161,6 +162,7 @@ namespace Kite { inline unsigned int KiteEngine::getRipupCost () const { return _configuration->getRipupCost(); } inline size_t KiteEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); } inline size_t KiteEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); } + inline bool KiteEngine::profileEventCosts () const { return _configuration->profileEventCosts(); } inline unsigned int KiteEngine::getRipupLimit ( unsigned int type ) const { return _configuration->getRipupLimit(type); } inline NegociateWindow* KiteEngine::getNegociateWindow () { return _negociateWindow; } inline size_t KiteEngine::getRoutingPlanesSize () const { return _routingPlanes.size(); }