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;