diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index 54c44a47..1a13e428 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -1501,8 +1501,9 @@ namespace Katabatic { ltrace(200) << "AutoSegment::canMoveUp() " << flags << " (reserve:" << reserve << ")" << endl; - GCell* begin = NULL; - GCell* end = NULL; + bool lowDensity = true; + GCell* begin = NULL; + GCell* end = NULL; if ( isLayerChange() or isFixed() ) return false; if ( isStrongTerminal() and (not (flags & KbAllowTerminal)) ) return false; @@ -1517,6 +1518,7 @@ namespace Katabatic { end = *gcells.rbegin(); for ( size_t i=0 ; igetWDensity(depth-2) > 0.5) ) lowDensity = false; if (not gcells[i]->hasFreeTrack(depth,reserve)) { ltrace(200) << "Not enough free track in " << gcells[i] << endl; return false; @@ -1542,6 +1544,7 @@ namespace Katabatic { if ( (*gcells.rbegin())->getIndex() > end ->getIndex() ) end = *gcells.rbegin(); for ( size_t i=0 ; igetWDensity(depth-2) > 0.6) ) lowDensity = false; if (not gcells[i]->hasFreeTrack(depth,reserve)) { ltrace(200) << "Not enough free track in " << gcells[i] << endl; return false; @@ -1550,6 +1553,8 @@ namespace Katabatic { } } + if (lowDensity and (flags & KbCheckLowDensity)) return false; + if ( (depth >= 4) and (flags & KbWithPerpands) ) { float fragmentation = begin->getFragmentation( depth-1 ); ltrace(200) << "Check begin GCell perpandicular fragmentation: " << fragmentation << endl; diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index 775994dd..0429edcb 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -1259,7 +1259,7 @@ namespace Katabatic { ltrace(500) << "Deter| Move up " << (*isegment) << endl; - if ( getGCellGrid()->getKatabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds) ) + if ( getGCellGrid()->getKatabatic()->moveUpNetTrunk2(*isegment,globalNets,invalidateds) ) return true; } diff --git a/katabatic/src/LayerAssign.cpp b/katabatic/src/LayerAssign.cpp index c833a6f7..ce5d5cbd 100644 --- a/katabatic/src/LayerAssign.cpp +++ b/katabatic/src/LayerAssign.cpp @@ -273,6 +273,100 @@ namespace Katabatic { } + bool KatabaticEngine::moveUpNetTrunk2 ( AutoSegment* seed, set& globalNets, GCell::SetIndex& invalidateds ) + { + Net* net = seed->getNet(); + unsigned int seedDepth = Session::getRoutingGauge()->getLayerDepth(seed->getLayer()); + + DebugSession::open( net, 90 ); + ltrace(500) << "Deter| moveUpNetTrunk() depth:" << seedDepth << " " << seed << endl; + + if (not seed->canMoveUp( 1.0, KbPropagate|KbAllowTerminal|KbNoCheckLayer) ) { + ltrace(500) << "Deter| Reject seed move up, cannot move up." << endl; + DebugSession::close(); + return false; + } + ltracein(400); + + globalNets.insert( net ); + + vector< pair > stack; + vector globals; + vector locals; + + stack.push_back( pair(NULL,seed) ); + while ( not stack.empty() ) { + AutoContact* from = stack.back().first; + AutoSegment* segment = stack.back().second; + stack.pop_back(); + + if (segment->isLocal()) { + if (not segment->isStrongTerminal()) locals.push_back( segment ); + continue; + } + if ( (segment->getLength() < 3*Session::getSliceHeight()) and (segment != seed) ) { + locals.push_back( segment ); + continue; + } + + // Do something here. + if (not segment->canMoveUp(1.0,KbPropagate|KbAllowTerminal|KbNoCheckLayer|KbCheckLowDensity) ) + continue; + + globals.push_back( segment ); + + AutoContact* source = segment->getAutoSource(); + if (source != from) { + for ( AutoSegment* connected : source->getAutoSegments() ) { + if (connected != segment) { stack.push_back( make_pair(source,connected) ); } + } + } + AutoContact* target = segment->getAutoTarget(); + if (target != from) { + for ( AutoSegment* connected : target->getAutoSegments() ) { + if (connected != segment) { stack.push_back( make_pair(target,connected) ); } + } + } + } + + for ( size_t i=0 ; igetLayerDepth( globals[i]->getLayer() ); + globals[i]->changeDepth( depth+2, KbWithNeighbors ); + + vector gcells; + globals[i]->getGCells( gcells ); + for ( size_t j=0 ; jgetLayerDepth(locals[i]->getLayer()); + if (depth > seedDepth+1) continue; + + if (locals[i]->canPivotUp(2.0,KbPropagate|KbNoCheckLayer)) { + locals[i]->changeDepth( depth+2, KbWithNeighbors ); + + //ltrace(500) << "Deter| Trunk move up L:" << locals[i] << endl; + + vector gcells; + locals[i]->getGCells( gcells ); + for ( size_t j=0 ; j& globalNets, GCell::SetIndex& invalidateds ) { Net* net = seed->getNet(); diff --git a/katabatic/src/katabatic/Constants.h b/katabatic/src/katabatic/Constants.h index 9754929a..af17beca 100644 --- a/katabatic/src/katabatic/Constants.h +++ b/katabatic/src/katabatic/Constants.h @@ -47,6 +47,7 @@ namespace Katabatic { , KbNoGCellShrink = 0x01000000 , KbCParanoid = 0x02000000 , KbCreate = 0x04000000 + , KbCheckLowDensity = 0x08000000 , KbDirectionMask = KbHorizontal|KbVertical }; diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index e8759abb..9d40a84c 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -146,6 +146,7 @@ namespace Katabatic { void slackenBorder ( Box bb, Layer::Mask, unsigned int flags ); void slackenBlockIos ( Instance* core ); bool moveUpNetTrunk ( AutoSegment*, set& globalNets, GCell::SetIndex& invalidateds ); + bool moveUpNetTrunk2 ( AutoSegment*, set& globalNets, GCell::SetIndex& invalidateds ); void moveULeft ( AutoSegment*, set& globalNets, GCell::SetIndex& invalidateds ); void moveURight ( AutoSegment*, set& globalNets, GCell::SetIndex& invalidateds ); void balanceGlobalDensity (); diff --git a/kite/src/SegmentFsm.cpp b/kite/src/SegmentFsm.cpp index 99863739..2cb57611 100644 --- a/kite/src/SegmentFsm.cpp +++ b/kite/src/SegmentFsm.cpp @@ -725,7 +725,7 @@ namespace Kite { Interval constraints; vector candidates; TrackElement* segment = _event->getSegment(); - bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); // MARK 1 + bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0,Katabatic::KbCheckLowDensity); // MARK 1 unsigned int relaxFlags = Manipulator::NoDoglegReuse | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand : Manipulator::NoExpand); @@ -1151,7 +1151,7 @@ namespace Kite { case DataNegociate::ConflictSolveByPlaceds: ltrace(200) << "Global, SegmentFsm: ConflictSolveByHistory or ConflictSolveByPlaceds." << endl; if ((success = conflictSolveByPlaceds())) { - if (segment->canMoveUp(1.0)) + if (segment->canMoveUp(1.0,Katabatic::KbCheckLowDensity)) nextState = DataNegociate::MoveUp; else { if (data->getStateCount() > 3)