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.
This commit is contained in:
Jean-Paul Chaput 2016-03-15 18:06:43 +01:00
parent da60370b60
commit 13c3efdefd
6 changed files with 106 additions and 5 deletions

View File

@ -1501,8 +1501,9 @@ namespace Katabatic {
ltrace(200) << "AutoSegment::canMoveUp() " << flags ltrace(200) << "AutoSegment::canMoveUp() " << flags
<< " (reserve:" << reserve << ")" << endl; << " (reserve:" << reserve << ")" << endl;
GCell* begin = NULL; bool lowDensity = true;
GCell* end = NULL; GCell* begin = NULL;
GCell* end = NULL;
if ( isLayerChange() or isFixed() ) return false; if ( isLayerChange() or isFixed() ) return false;
if ( isStrongTerminal() and (not (flags & KbAllowTerminal)) ) return false; if ( isStrongTerminal() and (not (flags & KbAllowTerminal)) ) return false;
@ -1517,6 +1518,7 @@ namespace Katabatic {
end = *gcells.rbegin(); end = *gcells.rbegin();
for ( size_t i=0 ; i<gcells.size() ; i++ ) { for ( size_t i=0 ; i<gcells.size() ; i++ ) {
if ( lowDensity and (gcells[i]->getWDensity(depth-2) > 0.5) ) lowDensity = false;
if (not gcells[i]->hasFreeTrack(depth,reserve)) { if (not gcells[i]->hasFreeTrack(depth,reserve)) {
ltrace(200) << "Not enough free track in " << gcells[i] << endl; ltrace(200) << "Not enough free track in " << gcells[i] << endl;
return false; return false;
@ -1542,6 +1544,7 @@ namespace Katabatic {
if ( (*gcells.rbegin())->getIndex() > end ->getIndex() ) end = *gcells.rbegin(); if ( (*gcells.rbegin())->getIndex() > end ->getIndex() ) end = *gcells.rbegin();
for ( size_t i=0 ; i<gcells.size() ; i++ ) { for ( size_t i=0 ; i<gcells.size() ; i++ ) {
if ( lowDensity and (gcells[i]->getWDensity(depth-2) > 0.6) ) lowDensity = false;
if (not gcells[i]->hasFreeTrack(depth,reserve)) { if (not gcells[i]->hasFreeTrack(depth,reserve)) {
ltrace(200) << "Not enough free track in " << gcells[i] << endl; ltrace(200) << "Not enough free track in " << gcells[i] << endl;
return false; return false;
@ -1550,6 +1553,8 @@ namespace Katabatic {
} }
} }
if (lowDensity and (flags & KbCheckLowDensity)) return false;
if ( (depth >= 4) and (flags & KbWithPerpands) ) { if ( (depth >= 4) and (flags & KbWithPerpands) ) {
float fragmentation = begin->getFragmentation( depth-1 ); float fragmentation = begin->getFragmentation( depth-1 );
ltrace(200) << "Check begin GCell perpandicular fragmentation: " << fragmentation << endl; ltrace(200) << "Check begin GCell perpandicular fragmentation: " << fragmentation << endl;

View File

@ -1259,7 +1259,7 @@ namespace Katabatic {
ltrace(500) << "Deter| Move up " << (*isegment) << endl; ltrace(500) << "Deter| Move up " << (*isegment) << endl;
if ( getGCellGrid()->getKatabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds) ) if ( getGCellGrid()->getKatabatic()->moveUpNetTrunk2(*isegment,globalNets,invalidateds) )
return true; return true;
} }

View File

@ -273,6 +273,100 @@ namespace Katabatic {
} }
bool KatabaticEngine::moveUpNetTrunk2 ( AutoSegment* seed, set<Net*>& 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<AutoContact*,AutoSegment*> > stack;
vector<AutoSegment*> globals;
vector<AutoSegment*> locals;
stack.push_back( pair<AutoContact*,AutoSegment*>(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 ; i<globals.size() ; ++i ) {
//ltrace(500) << "Deter| Looking up G:" << globals[i] << endl;
unsigned int depth = Session::getRoutingGauge()->getLayerDepth( globals[i]->getLayer() );
globals[i]->changeDepth( depth+2, KbWithNeighbors );
vector<GCell*> gcells;
globals[i]->getGCells( gcells );
for ( size_t j=0 ; j<gcells.size() ; j++ ) {
invalidateds.insert( gcells[j] );
}
}
for ( size_t i=0 ; i<locals.size() ; ++i ) {
//ltrace(500) << "Deter| Looking up L:" << locals[i] << endl;
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(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<GCell*> gcells;
locals[i]->getGCells( gcells );
for ( size_t j=0 ; j<gcells.size() ; j++ ) {
invalidateds.insert( gcells[j] );
}
}
}
ltraceout(400);
DebugSession::close();
return true;
}
bool KatabaticEngine::moveUpNetTrunk ( AutoSegment* seed, set<Net*>& globalNets, GCell::SetIndex& invalidateds ) bool KatabaticEngine::moveUpNetTrunk ( AutoSegment* seed, set<Net*>& globalNets, GCell::SetIndex& invalidateds )
{ {
Net* net = seed->getNet(); Net* net = seed->getNet();

View File

@ -47,6 +47,7 @@ namespace Katabatic {
, KbNoGCellShrink = 0x01000000 , KbNoGCellShrink = 0x01000000
, KbCParanoid = 0x02000000 , KbCParanoid = 0x02000000
, KbCreate = 0x04000000 , KbCreate = 0x04000000
, KbCheckLowDensity = 0x08000000
, KbDirectionMask = KbHorizontal|KbVertical , KbDirectionMask = KbHorizontal|KbVertical
}; };

View File

@ -146,6 +146,7 @@ namespace Katabatic {
void slackenBorder ( Box bb, Layer::Mask, unsigned int flags ); void slackenBorder ( Box bb, Layer::Mask, unsigned int flags );
void slackenBlockIos ( Instance* core ); void slackenBlockIos ( Instance* core );
bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::SetIndex& invalidateds ); bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::SetIndex& invalidateds );
bool moveUpNetTrunk2 ( AutoSegment*, set<Net*>& globalNets, GCell::SetIndex& invalidateds );
void moveULeft ( AutoSegment*, set<Net*>& globalNets, GCell::SetIndex& invalidateds ); void moveULeft ( AutoSegment*, set<Net*>& globalNets, GCell::SetIndex& invalidateds );
void moveURight ( AutoSegment*, set<Net*>& globalNets, GCell::SetIndex& invalidateds ); void moveURight ( AutoSegment*, set<Net*>& globalNets, GCell::SetIndex& invalidateds );
void balanceGlobalDensity (); void balanceGlobalDensity ();

View File

@ -725,7 +725,7 @@ namespace Kite {
Interval constraints; Interval constraints;
vector<Cs1Candidate> candidates; vector<Cs1Candidate> candidates;
TrackElement* segment = _event->getSegment(); 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 unsigned int relaxFlags = Manipulator::NoDoglegReuse
| ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand
: Manipulator::NoExpand); : Manipulator::NoExpand);
@ -1151,7 +1151,7 @@ namespace Kite {
case DataNegociate::ConflictSolveByPlaceds: case DataNegociate::ConflictSolveByPlaceds:
ltrace(200) << "Global, SegmentFsm: ConflictSolveByHistory or ConflictSolveByPlaceds." << endl; ltrace(200) << "Global, SegmentFsm: ConflictSolveByHistory or ConflictSolveByPlaceds." << endl;
if ((success = conflictSolveByPlaceds())) { if ((success = conflictSolveByPlaceds())) {
if (segment->canMoveUp(1.0)) if (segment->canMoveUp(1.0,Katabatic::KbCheckLowDensity))
nextState = DataNegociate::MoveUp; nextState = DataNegociate::MoveUp;
else { else {
if (data->getStateCount() > 3) if (data->getStateCount() > 3)