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
<< " (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 ; i<gcells.size() ; i++ ) {
if ( lowDensity and (gcells[i]->getWDensity(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 ; i<gcells.size() ; i++ ) {
if ( lowDensity and (gcells[i]->getWDensity(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;

View File

@ -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;
}

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 )
{
Net* net = seed->getNet();

View File

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

View File

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

View File

@ -725,7 +725,7 @@ namespace Kite {
Interval constraints;
vector<Cs1Candidate> 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)