From 13c3efdefdf9b5f655036891c1ead1c2189fcfd5 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 15 Mar 2016 18:06:43 +0100 Subject: [PATCH] In Katabatic, the layer assignment move up part of Net trunks. * In Katabatic, in AutoSegment::canMoveUp(), adds the ability to reject the move up if the density of the depth we comes from is below 0.6 in all the GCells, activated with the KbChecklowDensity flag. * In Katabatic, In LayerAssign, new method moveUpNetTrunk2() which, unlike the previous one, move up only the part of the Net trunk which is connex to the seed segment. Use the canMoveUp with low density checking to avoid unbalancing higher metal layers. * In Kite, in SegmentFsm, use the canMoveUp() with low density checking. --- katabatic/src/AutoSegment.cpp | 9 ++- katabatic/src/GCell.cpp | 2 +- katabatic/src/LayerAssign.cpp | 94 +++++++++++++++++++++++ katabatic/src/katabatic/Constants.h | 1 + katabatic/src/katabatic/KatabaticEngine.h | 1 + kite/src/SegmentFsm.cpp | 4 +- 6 files changed, 106 insertions(+), 5 deletions(-) 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)