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;