From bff9a38742fb1bd3cc6792dd48f5b50959a4d273 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 20 Sep 2016 11:30:45 +0200 Subject: [PATCH] Forgot to perform Track re-order after removing zero-length segments. * Change: In Anabatic::Autocontact, replace getMinDepth() and getMaxDepth() by getDepthSpan(). * New: In Anabatic::AutoSegment::canMoveUp(), add an optional check of low up density (Flags::CheckLowUpDensity). Allows to move up a segment if the up density is (very) low, and in this case it's more efficient than breaking it to fit in the lower layer. canMoveUp() is now able to perform the same work as canPivotUp() if *not* supplied the flag Flags::IgnoreContacts. * New: In Katana, in GlobalRouting::DigitalDistance() now take into account the cost of a VIA (currently set to 2.5). Need to known the Net currently routed in the DigitalDistance object itself. * Change: In Katana::Track::Element::canPivotUp(), now also takes a flag parameter. * Change: In Katana::Manipulator, new flag IgnoreContacts to mirror the one of Anabatic. * Change: In Katana::SegmentFsm, allocate once a Manipulator object instead of many times on the fly. In SegmentFsm::_slackenGlobal(), in the slacken state, if the up density is (very) low, bypass to move up instead of slackening. This solve better the routing of the control part of the register file. The register file having a pathological case of terminal placement: many punctual terminals aligneds in METAL2 *and* a grid of METAL2 and METAL3 blockages near below... * Bug: In Katana::Session::_revalidate(), after removing the zero-length segments, forgot to re-order the track, leading to many stranges effects as the indexes where no longer coherent in the Track. --- anabatic/src/AutoContact.cpp | 26 ++----- anabatic/src/AutoSegment.cpp | 103 ++++++++++++++++------------ anabatic/src/Constants.cpp | 3 +- anabatic/src/anabatic/AutoContact.h | 11 ++- anabatic/src/anabatic/Constants.h | 1 + anabatic/src/anabatic/Dijkstra.h | 4 +- katabatic/src/GCell.cpp | 2 +- katana/src/GlobalRoute.cpp | 23 +++++-- katana/src/Manipulator.cpp | 15 ++-- katana/src/PreProcess.cpp | 1 + katana/src/RoutingEvent.cpp | 2 +- katana/src/SegmentFsm.cpp | 64 ++++++++++------- katana/src/Session.cpp | 18 +---- katana/src/Track.cpp | 54 +++++++++------ katana/src/TrackElement.cpp | 4 +- katana/src/TrackSegment.cpp | 8 +-- katana/src/katana/DataNegociate.h | 2 +- katana/src/katana/Manipulator.h | 3 +- katana/src/katana/RoutingEvent.h | 2 +- katana/src/katana/RoutingPlane.h | 6 +- katana/src/katana/Track.h | 2 +- katana/src/katana/TrackElement.h | 4 +- katana/src/katana/TrackSegment.h | 4 +- 23 files changed, 200 insertions(+), 162 deletions(-) diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index c0825178..4e518188 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -183,35 +183,21 @@ namespace Anabatic { { return NULL; } - unsigned int AutoContact::getMinDepth () const + void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const { - size_t minDepth = (size_t)-1; + minDepth = (size_t)-1; + maxDepth = 0; + Component* anchor = getAnchor (); if (anchor) { minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); + maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); } for ( AutoSegment* segment : const_cast(this)->getAutoSegments() ) { minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); + maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); } - - return (unsigned int)minDepth; - } - - - unsigned int AutoContact::getMaxDepth () const - { - size_t maxDepth = 0; - Component* anchor = getAnchor (); - if ( anchor ) { - maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); - } - - for ( AutoSegment* segment : const_cast(this)->getAutoSegments() ) { - maxDepth = std::max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); - } - - return (unsigned int)maxDepth; } diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 2605e89d..b2f83c99 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -323,17 +323,18 @@ namespace Anabatic { , _parent (NULL) , _observers () { - AutoContact* source = Session::lookup(dynamic_cast(segment->getSource())); - AutoContact* target = Session::lookup(dynamic_cast(segment->getTarget())); - _allocateds++; if (dynamic_cast(segment)) setFlags( SegHorizontal ); - if (source->isTerminal()) setFlags( SegSourceTerminal ); - if (target->isTerminal()) setFlags( SegTargetTerminal ); _globalsCount += isGlobal() ? 1 : 0; + AutoContact* source = Session::lookup(dynamic_cast(segment->getSource())); + AutoContact* target = Session::lookup(dynamic_cast(segment->getTarget())); + + if (source->isTerminal()) setFlags( SegSourceTerminal ); + if (target->isTerminal()) setFlags( SegTargetTerminal ); + source->invalidate( Flags::Topology ); } @@ -859,21 +860,19 @@ namespace Anabatic { void AutoSegment::computeTerminal () { - AutoContact* source = getAutoSource(); - AutoContact* target = getAutoTarget(); - - cdebug_log(145,0) << "computeTerminal() S:" << source->isTerminal() - << " T:" << target->isTerminal() - << " " << this << endl; + AutoContact* source = getAutoSource(); + AutoContact* target = getAutoTarget(); if (source->isTerminal()) { unsetFlags( SegWeakTerminal ); setFlags ( SegSourceTerminal ); + if (not target->isTerminal()) target->setFlags( CntWeakTerminal ); } else if (target->isTerminal()) { unsetFlags( SegWeakTerminal ); setFlags ( SegTargetTerminal ); + if (not source->isTerminal()) source->setFlags( CntWeakTerminal ); } else { @@ -896,6 +895,10 @@ namespace Anabatic { unsetFlags( SegWeakTerminal ); setFlags ( terminalFlag ); } + + cdebug_log(145,0) << "computeTerminal() S:" << source->isTerminal() + << " T:" << target->isTerminal() + << " " << this << endl; } @@ -1400,7 +1403,8 @@ namespace Anabatic { << " (reserve:" << reserve << ")" << endl; if ( isLayerChange() or isFixed() ) return false; - if ( isStrongTerminal() or isLocal() ) return false; + if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false; + if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false; size_t depth = Session::getRoutingGauge()->getLayerDepth( getLayer() ); if (depth+2 >= Session::getRoutingGauge()->getDepth()) return false; @@ -1415,8 +1419,8 @@ namespace Anabatic { cdebug_log(149,0) << getAutoSource() << endl; cdebug_log(149,0) << getAutoTarget() << endl; cdebug_log(149,0) << "min depths, Segment:" << depth - << " S:" << getAutoSource()->getMinDepth() - << " T:" << getAutoTarget()->getMinDepth() << endl; + << " S:" << getAutoSource()->getMinDepth() + << " T:" << getAutoTarget()->getMinDepth() << endl; if (getAutoSource()->getMinDepth() < depth) return false; if (getAutoTarget()->getMinDepth() < depth) return false; @@ -1491,12 +1495,11 @@ namespace Anabatic { bool AutoSegment::canMoveUp ( float reserve, unsigned int flags ) const { - cdebug_log(149,0) << "AutoSegment::canMoveUp() " << flags - << " (reserve:" << reserve << ")" << endl; + cdebug_log(159,0) << "AutoSegment::canMoveUp() " << flags + << " (reserve:" << reserve << ") " << this << endl; - bool lowDensity = true; - GCell* begin = NULL; - GCell* end = NULL; + bool nLowDensity = true; + bool nLowUpDensity = true; if ( isLayerChange() or isFixed() ) return false; if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false; @@ -1507,65 +1510,79 @@ namespace Anabatic { vector gcells; getGCells( gcells ); - begin = *gcells.begin (); - end = *gcells.rbegin(); for ( size_t i=0 ; igetWDensity(depth-2) > 0.5) ) lowDensity = false; + if ( nLowDensity and (gcells[i]->getWDensity(depth-2) > 0.5) ) nLowDensity = false; + if ( nLowUpDensity and (gcells[i]->getWDensity(depth) > 0.2) ) nLowUpDensity = false; if (not gcells[i]->hasFreeTrack(depth,reserve)) { - cdebug_log(149,0) << "Not enough free track in " << gcells[i] << endl; + cdebug_log(159,0) << "Not enough free track in " << gcells[i] << endl; return false; } } - cdebug_log(149,0) << "Enough free track under canonical segment." << endl; + cdebug_log(159,0) << "Enough free track under canonical segment." << endl; + + if (not (flags & Flags::IgnoreContacts)) { + if (getAutoSource()->getMinDepth() < depth-2) return false; + if (getAutoTarget()->getMinDepth() < depth-2) return false; + } if ( isLocal() and not (flags & Flags::Propagate) ) { if (not getAutoSource()->canMoveUp(this)) return false; if (not getAutoTarget()->canMoveUp(this)) return false; return true; } + cdebug_log(159,0) << "Both source & target Contacts can move up." << endl; //bool hasGlobalSegment = false; if ((flags & Flags::Propagate) and not isNotAligned()) { - forEach ( AutoSegment*, isegment, const_cast(this)->getAligneds(flags) ) { - if (isegment->isFixed ()) return false; - //if (isegment->isGlobal()) hasGlobalSegment = true; + for ( AutoSegment* segment : const_cast(this)->getAligneds(flags) ) { + if (segment->isFixed ()) return false; + //if (segment->isGlobal()) hasGlobalSegment = true; - isegment->getGCells( gcells ); - //if ( (*gcells.begin ())->getIndex() < begin->getIndex() ) begin = *gcells.begin (); - //if ( (*gcells.rbegin())->getIndex() > end ->getIndex() ) end = *gcells.rbegin(); + if (not (flags & Flags::IgnoreContacts)) { + if (segment->getAutoSource()->getMinDepth() < depth-2) return false; + if (segment->getAutoTarget()->getMinDepth() < depth-2) return false; + } + + segment->getGCells( gcells ); for ( size_t i=0 ; igetWDensity(depth-2) > 0.6) ) lowDensity = false; + if ( nLowDensity and (gcells[i]->getWDensity(depth-2) > 0.6) ) nLowDensity = false; + if ( nLowUpDensity and (gcells[i]->getWDensity(depth) > 0.2) ) { + cdebug_log(159,0) << "lowUpDensity false in " << gcells[i] + << "d:" << gcells[i]->getWDensity(depth) << endl; + nLowUpDensity = false; + } if (not gcells[i]->hasFreeTrack(depth,reserve)) { - cdebug_log(149,0) << "Not enough free track in " << gcells[i] << endl; + cdebug_log(159,0) << "Not enough free track in " << gcells[i] << endl; return false; } } } } - if (lowDensity and (flags & Flags::CheckLowDensity)) return false; + if ( nLowDensity and (flags & Flags::CheckLowDensity )) return false; + if (not nLowUpDensity and (flags & Flags::CheckLowUpDensity)) return false; if ( (depth >= 4) and (flags & Flags::WithPerpands) ) { - float fragmentation = begin->getFragmentation( depth-1 ); - cdebug_log(149,0) << "Check begin GCell perpandicular fragmentation: " << fragmentation << endl; + float fragmentation = (*gcells.begin())->getFragmentation( depth-1 ); + cdebug_log(159,0) << "Check begin GCell perpandicular fragmentation: " << fragmentation << endl; if (fragmentation < 0.5) { - cdebug_log(149,0) << "Not enough free track for perpandicular in begin GCell " - << "(frag:" << fragmentation << ")." - << endl; + cdebug_log(159,0) << "Not enough free track for perpandicular in begin GCell " + << "(frag:" << fragmentation << ")." + << endl; return false; } - fragmentation = end->getFragmentation( depth-1 ); - cdebug_log(149,0) << "Check end GCell perpandicular fragmentation: " << fragmentation << endl; + fragmentation = (*gcells.rbegin())->getFragmentation( depth-1 ); + cdebug_log(159,0) << "Check end GCell perpandicular fragmentation: " << fragmentation << endl; if (fragmentation < 0.5) { - cdebug_log(149,0) << "Not enough free track for perpandicular in end GCell " - << "(frag:" << fragmentation << ")." - << endl; + cdebug_log(159,0) << "Not enough free track for perpandicular in end GCell " + << "(frag:" << fragmentation << ")." + << endl; return false; } } diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index 3dfc6b34..a659fb54 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -82,7 +82,8 @@ namespace Anabatic { const unsigned int Flags::NoGCellShrink = (1 << 27); const unsigned int Flags::CParanoid = (1 << 28); const unsigned int Flags::CheckLowDensity = (1 << 29); - const unsigned int Flags::NoUpdate = (1 << 30); + const unsigned int Flags::CheckLowUpDensity = (1 << 30); + const unsigned int Flags::NoUpdate = (1 << 31); Flags::~Flags () diff --git a/anabatic/src/anabatic/AutoContact.h b/anabatic/src/anabatic/AutoContact.h index eb605a39..70921038 100644 --- a/anabatic/src/anabatic/AutoContact.h +++ b/anabatic/src/anabatic/AutoContact.h @@ -125,8 +125,9 @@ namespace Anabatic { virtual AutoSegment* getOpposite ( const AutoSegment* ) const = 0; virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const = 0; virtual AutoSegment* getSegment ( unsigned int ) const = 0; - unsigned int getMinDepth () const; - unsigned int getMaxDepth () const; + void getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const; + inline unsigned int getMinDepth () const; + inline unsigned int getMaxDepth () const; void getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& ); virtual Box getNativeConstraintBox () const; Interval getNativeUConstraints ( unsigned int direction ) const; @@ -266,6 +267,12 @@ namespace Anabatic { inline DbU::Unit AutoContact::getCBYMax () const { return isFixed() ? _contact->getY() : DbU::fromLambda(_dyMax) + _gcell->getYMin(); } + inline unsigned int AutoContact::getMinDepth () const + { size_t minDepth, maxDepth; getDepthSpan(minDepth,maxDepth); return minDepth; } + + inline unsigned int AutoContact::getMaxDepth () const + { size_t minDepth, maxDepth; getDepthSpan(minDepth,maxDepth); return maxDepth; } + // ------------------------------------------------------------------- // Class : "Anabatic::LocatorHelper". diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index edde5d73..8bb732bd 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -84,6 +84,7 @@ namespace Anabatic { static const unsigned int NoGCellShrink ; static const unsigned int CParanoid ; static const unsigned int CheckLowDensity ; + static const unsigned int CheckLowUpDensity ; static const unsigned int NoUpdate ; public: inline Flags ( unsigned int flags = NoFlags ); diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index 29f5cc77..68435d66 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -64,7 +64,7 @@ namespace Anabatic { //inline Vertex ( size_t id ); inline ~Vertex (); inline bool hasDoneAllRps () const; - inline Contact* hasGContact ( Net* ); + inline Contact* hasGContact ( Net* ) const; inline unsigned int getId () const; inline GCell* getGCell () const; inline AnabaticEngine* getAnabatic () const; @@ -149,7 +149,7 @@ namespace Anabatic { inline Vertex::~Vertex () { _gcell->setObserver( GCell::Observable::Vertex, NULL ); } - inline Contact* Vertex::hasGContact ( Net* net ) { return _gcell->hasGContact(net); } + inline Contact* Vertex::hasGContact ( Net* net ) const { return _gcell->hasGContact(net); } inline unsigned int Vertex::getId () const { return _id; } inline GCell* Vertex::getGCell () const { return _gcell; } inline AnabaticEngine* Vertex::getAnabatic () const { return _gcell->getAnabatic(); } diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index 57ebcb0b..06499570 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -1317,7 +1317,7 @@ namespace Katabatic { ostringstream s; const Layer* layer = rg->getRoutingLayer(depth)->getBlockageLayer(); s << "_blockages[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; - record->add ( getSlot ( s.str(), &_blockages[depth] ) ); + record->add ( DbU::getValueSlot ( s.str(), &_blockages[depth] ) ); } for ( size_t depth=0 ; depth<_depth ; ++depth ) { diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index 6cbff892..0e30039e 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -28,6 +28,7 @@ namespace { using std::left; using std::right; using Hurricane::DbU; + using Hurricane::Net; using Anabatic::Edge; using Anabatic::Vertex; @@ -35,16 +36,19 @@ namespace { class DigitalDistance { public: inline DigitalDistance ( float h, float k ); + inline void setNet ( Net* ); DbU::Unit operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const; private: // For an explanation of h & k parameters, see: // "KNIK, routeur global pour la plateforme Coriolis", p. 52. float _h; float _k; + Net* _net; }; - inline DigitalDistance::DigitalDistance ( float h, float k ) : _h(h), _k(k) { } + inline DigitalDistance::DigitalDistance ( float h, float k ) : _h(h), _k(k), _net(NULL) { } + inline void DigitalDistance::setNet ( Net* net ) { _net = net; } DbU::Unit DigitalDistance::operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const @@ -54,8 +58,15 @@ namespace { float congestion = (float)edge->getRealOccupancy() / (float)edge->getCapacity(); float congestionCost = 1.0 + _h / (1.0 + std::exp(_k * (congestion - 1.0))); + float viaCost = 0.0; + if ( source->getFrom() + and (source->getFrom()->isHorizontal() xor edge->isHorizontal()) + and not source->hasGContact(_net) ) { + viaCost += 2.5; + } + float distance = (float)source->getDistance() - + congestionCost * (float)edge->getDistance(); + + (congestionCost + viaCost) * (float)edge->getDistance() + edge->getHistoricCost(); // Edge* sourceFrom = source->getFrom(); @@ -155,9 +166,10 @@ namespace Katana { float edgeHInc = getConfiguration()->getEdgeHInc(); openSession(); - Dijkstra* dijkstra = new Dijkstra ( this ); - dijkstra->setDistance( DigitalDistance( getConfiguration()->getEdgeCostH() - , getConfiguration()->getEdgeCostK() ) ); + Dijkstra* dijkstra = new Dijkstra ( this ); + DigitalDistance distance ( getConfiguration()->getEdgeCostH() + , getConfiguration()->getEdgeCostK() ); + dijkstra->setDistance( distance ); size_t iteration = 0; size_t netCount = 0; @@ -168,6 +180,7 @@ namespace Katana { for ( NetData* netData : getNetOrdering() ) { if (netData->isGlobalRouted()) continue; + distance.setNet( netData->getNet() ); dijkstra->load( netData->getNet() ); dijkstra->run(); ++netCount; diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index 1aa388b7..570259e5 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(), 150, 160 ); + DebugSession::open( _segment->getNet(), 149, 160 ); _data = _segment->getDataNegociate(); if (_data) _event = _data->getRoutingEvent(); @@ -1067,9 +1067,9 @@ namespace Katana { cdebug_log(159,0) << "Manipulator::pivotDown() " << _segment << endl; return false; - if ( _segment->isFixed () ) return false; - if ( _segment->isStrap () ) return false; - if (not _segment->canPivotDown(2.0)) return false; + if ( _segment->isFixed () ) return false; + if ( _segment->isStrap () ) return false; + if (not _segment->canPivotDown(2.0,Flags::NoFlags)) return false; return _segment->moveDown( Flags::NoFlags ); } @@ -1081,16 +1081,17 @@ namespace Katana { unsigned int kflags = Flags::WithNeighbors; //kflags |= (flags & AllowLocalMoveUp ) ? Flags::AutoSegment::AllowLocal : 0; - kflags |= (flags & AllowTerminalMoveUp) ? Flags::AllowTerminal : 0; + kflags |= (flags & AllowTerminalMoveUp) ? Flags::AllowTerminal : 0; + kflags |= (flags & IgnoreContacts ) ? Flags::IgnoreContacts : 0; if (_segment->isFixed()) return false; if (not (flags & AllowLocalMoveUp)) { if (_segment->isLocal()) { - if (not _segment->canPivotUp(0.5)) return false; + if (not _segment->canPivotUp(0.5,kflags)) return false; } else { if (_segment->getLength() < 20*getPitch()) { if (not (flags & AllowShortPivotUp)) return false; - if (not _segment->canPivotUp(1.0)) return false; + if (not _segment->canPivotUp(1.0,kflags)) return false; } if (not _segment->canMoveUp(0.5,kflags)) return false; } diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index 4f203326..8bb17e42 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -244,6 +244,7 @@ namespace { if (segment and segment->isFixed() and segment->isTerminal()) { Interval freeInterval = track->getFreeInterval( segment->getSourceU(), segment->getNet() ); DbU::Unit ppitch = segment->getPPitch(); + //DbU::Unit pitch = segment->getPitch(); //if (freeInterval.getSize() < ppitch*6) { if ( (segment->getSourceU() - freeInterval.getVMin() < ppitch*3) diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index d5fb1c84..70416e75 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -393,7 +393,7 @@ namespace Katana { #endif } - DebugSession::open( _segment->getNet(), 150, 160 ); + DebugSession::open( _segment->getNet(), 149, 160 ); cdebug_log(9000,0) << "Deter| Event " << getProcesseds() diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index 1f430870..119b788b 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -568,9 +568,9 @@ namespace Katana { void SegmentFsm::addAction ( TrackElement* segment - , unsigned int type - , DbU::Unit axisHint - , unsigned int toSegmentFsm ) + , unsigned int type + , DbU::Unit axisHint + , unsigned int toSegmentFsm ) { if ( not segment->isFixed() ) { _actions.push_back ( SegmentAction(segment,type,axisHint,toSegmentFsm) ); @@ -720,7 +720,7 @@ namespace Katana { Interval constraints; vector candidates; TrackElement* segment = _event->getSegment(); - bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0,Flags::CheckLowDensity); // MARK 1 + 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); @@ -1001,19 +1001,20 @@ namespace Katana { { cdebug_log(159,0) << "Strap segment Fsm." << endl; - bool success = false; - unsigned int nextState = data->getState(); + bool success = false; + unsigned int nextState = data->getState(); + Manipulator manipulator ( segment, *this ); switch ( data->getState() ) { case DataNegociate::RipupPerpandiculars: nextState = DataNegociate::Minimize; - success = Manipulator(segment,*this).ripupPerpandiculars(); + success = manipulator.ripupPerpandiculars(); if (success) break; case DataNegociate::Minimize: if (data->getStateCount() >= 2) { nextState = DataNegociate::MaximumSlack; } - success = Manipulator(segment,*this).minimize(); + success = manipulator.minimize(); if (success) break; case DataNegociate::Dogleg: case DataNegociate::Slacken: @@ -1027,7 +1028,7 @@ namespace Katana { } if (not success and (nextState != DataNegociate::Unimplemented)) - success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); + success = manipulator.ripupPerpandiculars(Manipulator::ToRipupLimit); if (not (flags&NoTransition)) { data->setState( nextState ); @@ -1042,13 +1043,14 @@ namespace Katana { { cdebug_log(159,0) << "Local segment Fsm." << endl; - bool success = false; - unsigned int nextState = data->getState(); + bool success = false; + unsigned int nextState = data->getState(); + Manipulator manipulator ( segment, *this ); switch (data->getState()) { case DataNegociate::RipupPerpandiculars: nextState = DataNegociate::Minimize; - success = Manipulator(segment,*this).ripupPerpandiculars(); + success = manipulator.ripupPerpandiculars(); if (success) break; case DataNegociate::Minimize: if (isFullBlocked() and not segment->isTerminal()) { @@ -1057,15 +1059,15 @@ namespace Katana { break; } nextState = DataNegociate::Dogleg; - success = Manipulator(segment,*this).minimize(); + success = manipulator.minimize(); if (success) break; case DataNegociate::Dogleg: nextState = DataNegociate::Slacken; - success = Manipulator(segment,*this).makeDogleg(); + success = manipulator.makeDogleg(); if (success) break; case DataNegociate::Slacken: nextState = DataNegociate::ConflictSolveByPlaceds; - success = Manipulator(segment,*this).slacken(); + success = manipulator.slacken(); if (success) break; case DataNegociate::ConflictSolveByHistory: case DataNegociate::ConflictSolveByPlaceds: @@ -1079,7 +1081,7 @@ namespace Katana { break; case DataNegociate::MoveUp: nextState = DataNegociate::MaximumSlack; - success = Manipulator(segment,*this).moveUp(); + success = manipulator.moveUp(); if (success) break; case DataNegociate::MaximumSlack: if (segment->isStrap()) { @@ -1096,7 +1098,7 @@ namespace Katana { if (not success and (nextState != DataNegociate::Unimplemented)) { if (data->getStateCount() < 6) - success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); + success = manipulator.ripupPerpandiculars(Manipulator::ToRipupLimit); } if (not success @@ -1117,8 +1119,10 @@ namespace Katana { bool SegmentFsm::_slackenGlobal ( TrackElement*& segment, DataNegociate*& data, unsigned int flags ) { - bool success = false; - unsigned int nextState = data->getState(); + bool success = false; + unsigned int nextState = data->getState(); + Manipulator manipulator ( segment, *this ); + unsigned int moveUpFlags = Manipulator::AllowShortPivotUp|Manipulator::IgnoreContacts; switch ( data->getState() ) { case DataNegociate::RipupPerpandiculars: @@ -1128,14 +1132,22 @@ namespace Katana { nextState = DataNegociate::Slacken; break; case DataNegociate::Slacken: - cdebug_log(159,0) << "Global, SegmentFsm: Slacken." << endl; - if ((success = Manipulator(segment,*this).slacken(Flags::HalfSlacken))) { - nextState = DataNegociate::RipupPerpandiculars; - break; + cdebug_log(159,0) << "Global, SegmentFsm: Slacken " + << ((manipulator.getEvent()) + ? manipulator.getEvent()->getConstraints() : "(not event yet)") << endl; + if ( manipulator.getEvent() + and manipulator.getEvent()->getConstraints().isPonctual() + and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) { + moveUpFlags |= Manipulator::AllowTerminalMoveUp; + } else { + if ((success = manipulator.slacken(Flags::HalfSlacken))) { + nextState = DataNegociate::RipupPerpandiculars; + break; + } } case DataNegociate::MoveUp: cdebug_log(159,0) << "Global, SegmentFsm: MoveUp." << endl; - if ((success = Manipulator(segment,*this).moveUp(Manipulator::AllowShortPivotUp))) { + if ((success = manipulator.moveUp(moveUpFlags))) { break; } nextState = DataNegociate::ConflictSolveByHistory; @@ -1155,7 +1167,7 @@ namespace Katana { break; } case DataNegociate::MaximumSlack: - if ((success=Manipulator(segment,*this).forceOverLocals())) { + if ((success=manipulator.forceOverLocals())) { break; } case DataNegociate::Unimplemented: @@ -1166,7 +1178,7 @@ namespace Katana { if (not success and (nextState != DataNegociate::Unimplemented)) { if (data->getStateCount() < 6) - success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); + success = manipulator.ripupPerpandiculars(Manipulator::ToRipupLimit); } // Special case: all tracks are overlaping a blockage. diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index c8f6a6ad..1c912158 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -21,6 +21,7 @@ #include "katana/Track.h" #include "katana/TrackElement.h" #include "katana/KatanaEngine.h" +#include "katana/RoutingPlane.h" namespace { @@ -207,25 +208,10 @@ namespace Katana { for ( size_t i=0 ; icheck(); } - - //_getKatanaEngine()->_showOverlap (); # endif _sortEvents.clear(); -#if THIS_IS_DISABLED - if (not faileds.empty()) { - set::iterator ifailed = faileds.begin(); - Anabatic::GCellVector gcells; - for ( ; ifailed != faileds.end() ; ++ifailed ) { - (*ifailed)->getGCells ( gcells ); - (*ifailed)->makeDogLeg( gcells[0] ); - } - - count += _revalidate(); - } -#endif - // Looking for reduced/raised segments. for ( size_t i=0 ; icanReduce()) { @@ -242,6 +228,8 @@ namespace Katana { } _doRemovalEvents(); + for ( Track* track : _sortEvents ) track->doReorder(); + _sortEvents.clear(); cdebug_tabw(159,-1); return count; diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 02049845..95589186 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -275,7 +275,7 @@ namespace Katana { if (_segments[end]->getSourceU() >= interval.getVMax()) break; } - cdebug_log(159,0) << "Track::getOverlapBounds(): begin:" << begin << " end:" << end << endl; + cdebug_log(155,0) << "Track::getOverlapBounds(): begin:" << begin << " end:" << end << endl; } @@ -287,7 +287,7 @@ namespace Katana { { TrackCost cost ( const_cast(this), interval, begin, end, net, flags ); - cdebug_log(159,1) << "getOverlapCost() @" << DbU::getValueString(_axis) + cdebug_log(155,1) << "getOverlapCost() @" << DbU::getValueString(_axis) << " [" << DbU::getValueString(interval.getVMin()) << ":" << DbU::getValueString(interval.getVMax()) << "] <-> [" << begin << ":" << end << "]" @@ -299,16 +299,16 @@ namespace Katana { for ( ; (mbegin < _markers.size()) and (_markers[mbegin]->getSourceU() <= interval.getVMax()) ; mbegin++ ) { - cdebug_log(159,0) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl; + cdebug_log(155,0) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl; if ( _markers[mbegin]->getNet() != net ) { - cdebug_log(159,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl; + cdebug_log(155,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl; cost.incTerminals( _markers[mbegin]->getWeight(this) ); } } if (begin == npos) { - cdebug_log(159,0) << " begin == npos (after last TrackElement)." << endl; - cdebug_tabw(159,-1); + cdebug_log(155,0) << " begin == npos (after last TrackElement)." << endl; + cdebug_tabw(155,-1); return cost; } @@ -317,12 +317,12 @@ namespace Katana { if ( _segments[begin]->getNet() == net ) { cost.incDeltaShared ( overlap.getSize() ); } - cdebug_log(159,0) << "| overlap: " << _segments[begin] << endl; + cdebug_log(155,0) << "| overlap: " << _segments[begin] << endl; _segments[begin]->incOverlapCost( net, cost ); if (cost.isInfinite()) break; } - cdebug_tabw(159,-1); + cdebug_tabw(155,-1); return cost; } @@ -345,7 +345,7 @@ namespace Katana { void Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, unsigned int& weight ) const { - cdebug_log(159,1) << "getTerminalWeight() @" << DbU::getValueString(_axis) + cdebug_log(155,1) << "getTerminalWeight() @" << DbU::getValueString(_axis) << " [" << interval.getVMin() << " " << interval.getVMax() << "]" << endl; //count = 0; @@ -357,14 +357,14 @@ namespace Katana { for ( ; (mbegin < _markers.size()) && (_markers[mbegin]->getSourceU() <= interval.getVMax()) ; mbegin++ ) { - cdebug_log(159,0) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl; + cdebug_log(155,0) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl; if ( _markers[mbegin]->getNet() == net ) { - cdebug_log(159,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl; + cdebug_log(155,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl; weight += _markers[mbegin]->getWeight(this); ++count; } } - cdebug_tabw(159,-1); + cdebug_tabw(155,-1); } @@ -409,7 +409,11 @@ namespace Katana { Interval Track::expandFreeInterval ( size_t& begin, size_t& end, unsigned int state, Net* net ) const { + cdebug_log(155,1) << "Track::expandFreeInterval() begin:" << begin << " end:" << end << " " << net << endl; + cdebug_log(155,0) << _segments[begin] << endl; + DbU::Unit minFree = _min; + cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " (track min)" << endl; if (not (state & BeginIsTrackMin) ) { if (_segments[begin]->getNet() == net) @@ -417,6 +421,7 @@ namespace Katana { if (begin != npos) { minFree = getOccupiedInterval(begin).getVMax(); + cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " begin:" << begin << endl; } } @@ -432,6 +437,7 @@ namespace Katana { } } } + cdebug_tabw(155,-1); return Interval( minFree, getMaximalPosition(end,state) ); } @@ -452,7 +458,7 @@ namespace Katana { { // cdebug_log(9000,0) << "Deter| Track::insert() " << getLayer()->getName() // << " @" << DbU::getValueString(getAxis()) << " " << segment << endl; - cdebug_log(159,0) << "Track::insert() " << getLayer()->getName() + cdebug_log(155,0) << "Track::insert() " << getLayer()->getName() << " @" << DbU::getValueString(getAxis()) << " " << segment << endl; if ( (getLayer()->getMask() != segment->getLayer()->getMask()) @@ -596,10 +602,14 @@ namespace Katana { Interval mergedInterval; _segments[seed]->getCanonical( mergedInterval ); + cdebug_log(155,0) << "| seed:" << _segments[seed] << endl; + size_t i = seed; while ( --i != npos ) { if (_segments[i]->getNet() != owner) break; + cdebug_log(155,0) << "| merge:" << _segments[i] << endl; + _segments[i]->getCanonical ( segmentInterval ); if (segmentInterval.getVMax() >= mergedInterval.getVMin()) { mergedInterval.merge( segmentInterval ); @@ -623,7 +633,7 @@ namespace Katana { size_t Track::doRemoval () { - cdebug_log(159,1) << "Track::doRemoval() - " << this << endl; + cdebug_log(155,1) << "Track::doRemoval() - " << this << endl; size_t size = _segments.size(); @@ -632,8 +642,8 @@ namespace Katana { _segments.erase( beginRemove, _segments.end() ); - cdebug_log(159,0) << "After doRemoval " << this << endl; - cdebug_tabw(159,-1); + cdebug_log(155,0) << "After doRemoval " << this << endl; + cdebug_tabw(155,-1); return size - _segments.size(); } @@ -641,18 +651,18 @@ namespace Katana { void Track::doReorder () { - cdebug_log(159,0) << "Track::doReorder() " << this << endl; + cdebug_log(155,0) << "Track::doReorder() " << this << endl; - if (not _segmentsValid ) { - std::sort ( _segments.begin(), _segments.end(), SegmentCompare() ); + if (not _segmentsValid) { + std::sort( _segments.begin(), _segments.end(), SegmentCompare() ); for ( size_t i=0 ; i < _segments.size() ; i++ ) { - _segments[i]->setIndex ( i ); + _segments[i]->setIndex( i ); } _segmentsValid = true; } - if (not _markersValid ) { - std::sort ( _markers.begin(), _markers.end(), TrackMarker::Compare() ); + if (not _markersValid) { + std::sort( _markers.begin(), _markers.end(), TrackMarker::Compare() ); _markersValid = true; } } diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 0eec425b..effc22d1 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -146,8 +146,8 @@ namespace Katana { bool TrackElement::isUserDefined () const { return false; } // Predicates. bool TrackElement::canSlacken () const { return false; } - bool TrackElement::canPivotUp ( float ) const { return false; }; - bool TrackElement::canPivotDown ( float ) const { return false; }; + bool TrackElement::canPivotUp ( float, unsigned int ) const { return false; }; + bool TrackElement::canPivotDown ( float, unsigned int ) const { return false; }; bool TrackElement::canMoveUp ( float, unsigned int ) const { return false; }; bool TrackElement::canDogleg () { return false; }; bool TrackElement::canDogleg ( Interval ) { return false; }; diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index c8d6ecc8..6b2056b6 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -406,12 +406,12 @@ namespace Katana { { return _base->getMaxUnderDensity( flags ); } - bool TrackSegment::canPivotUp ( float reserve ) const - { return _base->canPivotUp(reserve); } + bool TrackSegment::canPivotUp ( float reserve, unsigned int flags ) const + { return _base->canPivotUp( reserve, flags ); } - bool TrackSegment::canPivotDown ( float reserve ) const - { return _base->canPivotDown( reserve ); } + bool TrackSegment::canPivotDown ( float reserve, unsigned int flags ) const + { return _base->canPivotDown( reserve, flags ); } bool TrackSegment::canMoveUp ( float reserve, unsigned int flags ) const diff --git a/katana/src/katana/DataNegociate.h b/katana/src/katana/DataNegociate.h index bbdc49ce..5a6af59b 100644 --- a/katana/src/katana/DataNegociate.h +++ b/katana/src/katana/DataNegociate.h @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/DataNegociate.h" | +// | C++ Header : "./katana/DataNegociate.h" | // +-----------------------------------------------------------------+ diff --git a/katana/src/katana/Manipulator.h b/katana/src/katana/Manipulator.h index 348944f9..80881105 100644 --- a/katana/src/katana/Manipulator.h +++ b/katana/src/katana/Manipulator.h @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/Manipulator.h" | +// | C++ Header : "./katana/Manipulator.h" | // +-----------------------------------------------------------------+ @@ -48,6 +48,7 @@ namespace Katana { , LeftAxisHint = 0x0200 , RightAxisHint = 0x0400 , NotOnLastRipup = 0x0800 + , IgnoreContacts = 0x1000 }; public: Manipulator ( TrackElement*, SegmentFsm& ); diff --git a/katana/src/katana/RoutingEvent.h b/katana/src/katana/RoutingEvent.h index 74a2a72c..bde388e3 100644 --- a/katana/src/katana/RoutingEvent.h +++ b/katana/src/katana/RoutingEvent.h @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/RoutingEvent.h" | +// | C++ Header : "./katana/RoutingEvent.h" | // +-----------------------------------------------------------------+ diff --git a/katana/src/katana/RoutingPlane.h b/katana/src/katana/RoutingPlane.h index dd604ed7..4300532e 100644 --- a/katana/src/katana/RoutingPlane.h +++ b/katana/src/katana/RoutingPlane.h @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/RoutingPlane.h" | +// | C++ Header : "./katana/RoutingPlane.h" | // +-----------------------------------------------------------------+ @@ -37,7 +37,7 @@ namespace Katana { void destroy (); inline bool isHorizontal () const; inline bool isVertical () const; - inline KatanaEngine* getKatanaEngine () const; + inline KatanaEngine* getKatanaEngine () const; inline RoutingLayerGauge* getLayerGauge () const; inline unsigned int getDirection () const; inline size_t getDepth () const; @@ -91,7 +91,7 @@ namespace Katana { inline bool RoutingPlane::TrackCompare::operator() ( Track* lhs, Track* rhs ) { return lhs->getAxis() > rhs->getAxis(); }; - inline KatanaEngine* RoutingPlane::getKatanaEngine () const { return _katana; } + inline KatanaEngine* RoutingPlane::getKatanaEngine () const { return _katana; } inline RoutingLayerGauge* RoutingPlane::getLayerGauge () const { return _layerGauge; } inline unsigned int RoutingPlane::getDirection () const { return _flags & Flags::DirectionMask; } inline size_t RoutingPlane::getDepth () const { return _depth; } diff --git a/katana/src/katana/Track.h b/katana/src/katana/Track.h index dc70ad24..bf050381 100644 --- a/katana/src/katana/Track.h +++ b/katana/src/katana/Track.h @@ -10,7 +10,7 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./katana/Track.h" | +// | C++ Header : "./katana/Track.h" | // +-----------------------------------------------------------------+ diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index 0fb05005..e5b628a6 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -115,8 +115,8 @@ namespace Katana { inline bool hasTargetDogleg () const; inline bool canRipple () const; virtual bool canSlacken () const; - virtual bool canPivotUp ( float reserve ) const; - virtual bool canPivotDown ( float reserve ) const; + virtual bool canPivotUp ( float reserve, unsigned int flags ) const; + virtual bool canPivotDown ( float reserve, unsigned int flags ) const; virtual bool canMoveUp ( float reserve, unsigned int flags=Flags::WithPerpands ) const; virtual bool canDogleg (); virtual bool canDogleg ( Interval ); diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index 8ff4886b..033904d4 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -75,8 +75,8 @@ namespace Katana { virtual bool canDogleg (); virtual bool canDogleg ( Interval ); virtual bool canDogleg ( Anabatic::GCell*, unsigned int flags=0 ); - virtual bool canPivotUp ( float reserve ) const; - virtual bool canPivotDown ( float reserve ) const; + virtual bool canPivotUp ( float reserve, unsigned int flags ) const; + virtual bool canPivotDown ( float reserve, unsigned int flags ) const; virtual bool canMoveUp ( float reserve, unsigned int flags ) const; virtual bool canSlacken () const; virtual float getMaxUnderDensity ( unsigned int flags ) const;