diff --git a/katabatic/src/AutoContact.cpp b/katabatic/src/AutoContact.cpp index 40d4920b..b05cfa14 100644 --- a/katabatic/src/AutoContact.cpp +++ b/katabatic/src/AutoContact.cpp @@ -331,7 +331,7 @@ namespace { inline string SegmentEnd::_getTypeName () const { return "Katabatic::SegmentEnd"; } inline bool SegmentEnd::Compare::operator() ( const SegmentEnd* lhs, const SegmentEnd* rhs ) const - { return AutoSegment::CompareCanonical() ( lhs->getSegment(), rhs->getSegment() ); } + { return AutoSegment::CompareId() ( lhs->getSegment(), rhs->getSegment() ); } inline SegmentEnd::SegmentEnd ( AutoSegment* segment, bool isSourceHook ) : _autoSegment(segment) @@ -1535,15 +1535,32 @@ namespace { , _routingGauge->getLayerDirection(zMin+1) , AutoSegment::Local ); - DbU::Unit axis = (segment->isHorizontal()) ? position.getY() : position.getX(); + DbU::Unit axis; + if ( segment->isHorizontal() ) { + axis = position.getY(); + if ( not hBottom.empty() ) segment->setParent ( hBottom[0]->getSegment() ); + else if ( not hTop .empty() ) segment->setParent ( hTop [0]->getSegment() ); + } else { + axis = position.getX(); + if ( not vBottom.empty() ) segment->setParent ( vBottom[0]->getSegment() ); + else if ( not vTop .empty() ) segment->setParent ( vTop [0]->getSegment() ); + } + segment->setLayer ( _routingGauge->getRoutingLayer(zMin+1) ); segment->setAxis ( axis ); segment->setSlackened ( true ); segment->setLayerChange ( true ); ltrace(200) << "Corner @" << DbU::getValueString(axis) << " " << segment << endl; - if ( vExtended ) _contact->setVAlignate ( true ); - if ( hExtended ) _contact->setHAlignate ( true ); + //if ( vExtended ) _contact->setVAlignate ( true ); + //if ( hExtended ) _contact->setHAlignate ( true ); + // if ( _routingGauge->getLayerDirection(zMin) == Constant::Horizontal ) { + // _contact->setVAlignate ( true ); + // } else { + // _contact->setHAlignate ( true ); + // } + //_contact->setHAlignate ( true ); + //_contact->setVAlignate ( true ); AutoContact* secondary = NULL; if ( zMax-zMin == 3 ) { @@ -1558,33 +1575,88 @@ namespace { , _routingGauge->getLayerDirection(zMin+2) , AutoSegment::Local ); + + if ( segment->isHorizontal() ) { + axis = position.getY(); + if ( not hTop .empty() ) segment->setParent ( hTop [0]->getSegment() ); + else if ( not hBottom.empty() ) segment->setParent ( hBottom[0]->getSegment() ); + } else { + axis = position.getX(); + if ( not vTop .empty() ) segment->setParent ( vTop [0]->getSegment() ); + else if ( not vBottom.empty() ) segment->setParent ( vBottom[0]->getSegment() ); + } + axis = (segment->isHorizontal()) ? position.getY() : position.getX(); segment->setLayer ( _routingGauge->getRoutingLayer(zMin+2) ); segment->setAxis ( axis ); - segment->setCanonical ( true ); + //segment->setCanonical ( true ); segment->setSlackened ( true ); segment->setLayerChange ( true ); ltrace(200) << "Secondary @" << DbU::getValueString(axis) << " " << segment << endl; + } else secondary = corner; + // if ( _routingGauge->getLayerDirection(zMin) == Constant::Horizontal ) { + // secondary->setHAlignate ( true ); + // } else { + // secondary->setVAlignate ( true ); + // } + //secondary->setVAlignate(true); + //secondary->setHAlignate(true); + for ( size_t i=0 ; igetHook()->attach ( secondary->getBodyHook() ); for ( size_t i=0 ; igetHook()->attach ( secondary->getBodyHook() ); - if ( _contact->isVAlignate() ) secondary->setVAlignate(true); - if ( _contact->isHAlignate() ) secondary->setHAlignate(true); + if ( _contact->isHAlignate() ) secondary->setHAlignate ( true ); + if ( _contact->isVAlignate() ) secondary->setVAlignate ( true ); - if ( hExtended ) { - ltrace(200) << "Original was H extended: restore V connexity." << endl; - _contact ->restoreVConnexity ( position.getY(), true ); - secondary->restoreVConnexity ( position.getY(), true ); + if ( _globalStem ) { + AutoContact* withoutStem = (_routingGauge->getLayerDepth(_globalStem->getLayer()) < zMin+2) + ? secondary : _contact; + + if ( _globalStem->isHorizontal() ) { + withoutStem->setHAlignate ( true ); + withoutStem->restoreVConnexity ( position.getY(), true ); + } else { + withoutStem->setVAlignate ( true ); + withoutStem->restoreHConnexity ( position.getX(), true ); + } + } else { + if ( _routingGauge->getLayerDirection(zMin) == Constant::Horizontal ) { + _contact ->setVAlignate ( true ); + secondary->setHAlignate ( true ); + } else { + _contact ->setHAlignate ( true ); + secondary->setVAlignate ( true ); + } } - if ( vExtended ) { - ltrace(200) << "Original was V extended: restore H connexity." << endl; - _contact ->restoreHConnexity ( position.getX(), true ); - secondary->restoreHConnexity ( position.getX(), true ); - } + // if ( _routingGauge->getLayerDirection(zMin) == Constant::Horizontal ) { + // _contact ->restoreHConnexity ( position.getX(), true ); + // secondary->restoreVConnexity ( position.getY(), true ); + // } else { + // _contact ->restoreVConnexity ( position.getY(), true ); + // secondary->restoreHConnexity ( position.getX(), true ); + // } + + // if ( _contact->isVAlignate() ) secondary->setVAlignate(true); + // if ( _contact->isHAlignate() ) secondary->setHAlignate(true); + + + // if ( (not hExtended) and (not vExtended) ) hExtended = true; + + // if ( hExtended ) { + // ltrace(200) << "Original was H extended: restore V connexity." << endl; + // _contact ->restoreVConnexity ( position.getY(), true ); + // secondary->restoreVConnexity ( position.getY(), true ); + // } + + // if ( vExtended ) { + // ltrace(200) << "Original was V extended: restore H connexity." << endl; + // _contact ->restoreHConnexity ( position.getX(), true ); + // secondary->restoreHConnexity ( position.getX(), true ); + // } ltraceout(200); } @@ -1599,7 +1671,7 @@ namespace { _contact->getAnchorHook()->detach (); RoutingPad* routingPad = dynamic_cast ( _anchor ); - if ( !routingPad ) { + if ( not routingPad ) { cerr << Bug("JunctionBox::splitTerminal(): %s is not anchored on a ." ,getString(_contact).c_str()) << endl; ltraceout(200); @@ -2259,6 +2331,24 @@ namespace Katabatic { } + unsigned int AutoContact::getMaxDepth () const + { + size_t maxDepth = 0; + Component* anchor = getAnchor (); + if ( anchor ) { + maxDepth = max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); + //ltrace(200) << "Anchor:" << anchor << endl; + } + + forEach ( Component*, icomponent, getSlaveComponents() ) { + maxDepth = max ( maxDepth, Session::getRoutingGauge()->getLayerDepth(icomponent->getLayer()) ); + //ltrace(200) << "Slave:" << *icomponent << endl; + } + + return (unsigned int)maxDepth; + } + + void AutoContact::getLengths ( DbU::Unit* lengths, set& processeds ) { forEach ( Hook*, ihook, getBodyHook()->getSlaveHooks() ) { diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index 7febb34c..0a00aacc 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -249,50 +249,40 @@ namespace { namespace Katabatic { -// ------------------------------------------------------------------- -// Class : "Katabatic::AutoSegment::CompareCanonical". - - - bool AutoSegment::CompareCanonical::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const - { - if ( lhs->isCanonical () xor rhs->isCanonical () ) return lhs->isCanonical(); - if ( lhs->isCollapsed () xor rhs->isCollapsed () ) return rhs->isCollapsed(); - if ( lhs->isSlackenStrap() xor rhs->isSlackenStrap() ) return lhs->isSlackenStrap(); - - if ( lhs->getSourceU() < rhs->getSourceU() ) return true; - if ( lhs->getSourceU() > rhs->getSourceU() ) return false; - - if ( lhs->getLength() > rhs->getLength() ) return true; - if ( lhs->getLength() < rhs->getLength() ) return false; - - if ( lhs->isGlobal () xor rhs->isGlobal () ) return lhs->isGlobal(); - if ( lhs->isTerminal () xor rhs->isTerminal () ) return rhs->isTerminal(); - if ( lhs->isHorizontal() xor rhs->isHorizontal() ) return lhs->isHorizontal(); - - if ( lhs->getAxis() < rhs->getAxis() ) return true; - if ( lhs->getAxis() > rhs->getAxis() ) return false; - - if ( lhs->isFixed() xor rhs->isFixed() ) return lhs->isFixed(); - - return lhs->getId() < rhs->getId(); - } - - // ------------------------------------------------------------------- // Class : "Katabatic::AutoSegment::CompareByDepthLength". bool AutoSegment::CompareByDepthLength::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const { - if ( Session::getRoutingGauge()->getLayerDepth(lhs->getLayer()) - < Session::getRoutingGauge()->getLayerDepth(rhs->getLayer()) ) - return true; + int deltaDepth = (int)(Session::getRoutingGauge()->getLayerDepth(lhs->getLayer())) + - (int)(Session::getRoutingGauge()->getLayerDepth(rhs->getLayer())); + if ( deltaDepth < 0 ) return true; // Lowest layer first. + if ( deltaDepth > 0 ) return false; - if ( Session::getRoutingGauge()->getLayerDepth(lhs->getLayer()) - > Session::getRoutingGauge()->getLayerDepth(rhs->getLayer()) ) - return false; + DbU::Unit deltaUnit = lhs->getSourceU() - rhs->getSourceU(); + if ( deltaUnit < 0 ) return true; // Smallest source first. + if ( deltaUnit > 0 ) return false; - return AutoSegment::CompareCanonical() ( lhs, rhs ); + deltaUnit = lhs->getLength() - rhs->getLength(); + if ( deltaUnit > 0 ) return true; // Longest first. + if ( deltaUnit < 0 ) return true; + + deltaUnit = lhs->getAxis() - rhs->getAxis(); + if ( deltaUnit < 0 ) return true; // Smallest axis first. + if ( deltaUnit > 0 ) return false; + + // if ( lhs->isCanonical () xor rhs->isCanonical () ) return lhs->isCanonical(); + // if ( lhs->isCollapsed () xor rhs->isCollapsed () ) return rhs->isCollapsed(); + // if ( lhs->isSlackenStrap() xor rhs->isSlackenStrap() ) return lhs->isSlackenStrap(); + + // if ( lhs->isGlobal () xor rhs->isGlobal () ) return lhs->isGlobal(); + // if ( lhs->isTerminal () xor rhs->isTerminal () ) return rhs->isTerminal(); + // if ( lhs->isHorizontal() xor rhs->isHorizontal() ) return lhs->isHorizontal(); + + // if ( lhs->isFixed() xor rhs->isFixed() ) return lhs->isFixed(); + + return lhs->getId() < rhs->getId(); } @@ -790,8 +780,8 @@ namespace Katabatic { break; } - if ( !hasCanonical ) { - if ( CompareCanonical()(*isegment,canonical) ) + if ( not hasCanonical ) { + if ( CompareId()(*isegment,canonical) ) canonical = *isegment; } } @@ -833,6 +823,7 @@ namespace Katabatic { , _id (_maxId++) , _optimalMin (0) , _userConstraints (false) + , _parent (NULL) { //cerr << "AutoSegment::AutoSegment() - " << endl; #if defined(CHECK_DETERMINISM) @@ -1251,12 +1242,12 @@ namespace Katabatic { } - bool AutoSegment::canPivotUp ( bool propagate, float reserve ) + bool AutoSegment::canPivotUp ( float reserve, unsigned int flags ) { - ltrace(200) << "AutoSegment::canPivotUp()" << endl; + ltrace(200) << "AutoSegment::canPivotUp() - " << flags << endl; if ( isLayerChange() or isFixed() ) return false; - if ( isTerminal() or isLocal() ) return false; + if ( isTerminal () or isLocal() ) return false; //if ( isTerminal() ) return false; @@ -1266,19 +1257,67 @@ namespace Katabatic { vector gcells; getGCells ( gcells ); for ( size_t i=0 ; ihasFreeTrack(depth,reserve) ) return false; + if ( not gcells[i]->hasFreeTrack(depth+2,reserve) ) return false; + } + + if ( not (flags&IgnoreContact) ) { + ltrace(200) << getAutoSource() << endl; + ltrace(200) << getAutoTarget() << endl; + ltrace(200) << "min depths, Segment:" << depth + << " S:" << getAutoSource()->getMinDepth() + << " T:" << getAutoTarget()->getMinDepth() << endl; + + if ( getAutoSource()->getMinDepth() < depth ) return false; + if ( getAutoTarget()->getMinDepth() < depth ) return false; + } + + if ( flags & Propagate ) { + forEach ( AutoSegment*, isegment, getCollapseds() ) { + isegment->getGCells ( gcells ); + for ( size_t i=0 ; ihasFreeTrack(depth+2,reserve) ) return false; + } + if ( isegment->getAutoSource()->getMinDepth() < depth ) return false; + if ( isegment->getAutoTarget()->getMinDepth() < depth ) return false; + } + } else { + ltrace(200) << "AutoSegment::canPivotUp() - true [no propagate]" << endl; + return true; + } + + ltrace(200) << "AutoSegment::canPivotUp() - true [propagate]" << endl; + + return true; + } + + + bool AutoSegment::canPivotDown ( bool propagate, float reserve ) + { + ltrace(200) << "AutoSegment::canPivotDown()" << endl; + + if ( isLayerChange() or isFixed() ) return false; + if ( isTerminal () or isLocal() ) return false; + //if ( isTerminal () ) return false; + + size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()); + if ( depth < 3 ) return false; + + vector gcells; + getGCells ( gcells ); + for ( size_t i=0 ; ihasFreeTrack(depth-2,reserve) ) return false; } ltrace(200) << getAutoSource() << endl; ltrace(200) << getAutoTarget() << endl; - ltrace(200) << "min depths, Segment:" << depth - << " S:" << getAutoSource()->getMinDepth() - << " T:" << getAutoTarget()->getMinDepth() << endl; + ltrace(200) << "max depths, Segment:" << depth + << " S:" << getAutoSource()->getMaxDepth() + << " T:" << getAutoTarget()->getMaxDepth() << endl; - if ( getAutoSource()->getMinDepth() < depth ) return false; - if ( getAutoTarget()->getMinDepth() < depth ) return false; + if ( getAutoSource()->getMaxDepth() > depth ) return false; + if ( getAutoTarget()->getMaxDepth() > depth ) return false; if ( not propagate ) { - ltrace(200) << "AutoSegment::canPivotUp() - true [no propagate]" << endl; + ltrace(200) << "AutoSegment::canPivotDown() - true [no propagate]" << endl; return true; } @@ -1286,10 +1325,10 @@ namespace Katabatic { forEach ( AutoSegment*, isegment, getCollapseds() ) { isegment->getGCells ( gcells ); for ( size_t i=0 ; ihasFreeTrack(depth,reserve) ) return false; + if ( not gcells[i]->hasFreeTrack(depth-2,reserve) ) return false; } - if ( isegment->getAutoSource()->getMinDepth() < depth ) return false; - if ( isegment->getAutoTarget()->getMinDepth() < depth ) return false; + if ( isegment->getAutoSource()->getMaxDepth() < depth ) return false; + if ( isegment->getAutoTarget()->getMaxDepth() < depth ) return false; } } @@ -1356,6 +1395,15 @@ namespace Katabatic { } + bool AutoSegment::moveDown ( unsigned int flags ) + { + if ( not canPivotDown(0.0,flags) ) return false; + changeDepth ( Session::getRoutingGauge()->getLayerDepth(getLayer()) - 2, flags&Propagate ); + + return true; + } + + bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, unsigned int flags ) { ltrace(200) << "AutoSegment::shearUp() " << this << endl; diff --git a/katabatic/src/ChipTools.cpp b/katabatic/src/ChipTools.cpp index faf920d8..e1fca00f 100644 --- a/katabatic/src/ChipTools.cpp +++ b/katabatic/src/ChipTools.cpp @@ -31,6 +31,7 @@ #include "hurricane/Technology.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" +#include "hurricane/RoutingPad.h" #include "crlcore/RoutingGauge.h" #include "crlcore/AllianceFramework.h" #include "katabatic/Session.h" @@ -131,6 +132,27 @@ namespace { } + void reselectPadRp ( Cell* cell ) + { + AllianceFramework* af = AllianceFramework::get(); + + forEach ( Net*, inet, cell->getNets() ) { + if ( inet->getType() == Net::Type::GROUND ) continue; + if ( inet->getType() == Net::Type::POWER ) continue; + if ( inet->getType() == Net::Type::CLOCK ) continue; + + forEach ( RoutingPad*, irp, inet->getRoutingPads() ) { + Instance* instance = irp->getOccurrence().getPath().getTailInstance(); + if ( instance ) { + Cell* masterCell = instance->getMasterCell(); + if ( af->isPad(masterCell) ) + irp->setOnBestComponent(RoutingPad::LowestLayer); + } + } // RoutingPad*. + } // Net*. + } + + } // End of anonymous namespace. @@ -168,6 +190,7 @@ namespace Katabatic { void KatabaticEngine::chipPrep () { if ( isChip() ) { + reselectPadRp ( getCell() ); // slackenBlockIos ( _core ); // cmess1 << " o Slackening Pads-connected segments." << endl; diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index 37adf362..67ef293b 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -113,18 +113,18 @@ namespace Katabatic { , _box (box) , _depth (Session::getRoutingGauge()->getDepth()) , _pinDepth (0) - , _blockages (new float [_depth]) + , _blockages (new DbU::Unit [_depth]) , _cDensity (0.0) , _densities (new float [_depth]) - , _saturateDensities (new float [_depth]) + // , _saturateDensities (new float [_depth]) , _saturated (false) , _invalid (true) , _key (0.0,_index) { for ( size_t i=0 ; i<_depth ; i++ ) { - _blockages [i] = 0.0; + _blockages [i] = 0; _densities [i] = 0.0; - _saturateDensities[i] = 0.0; + //_saturateDensities[i] = 0.0; if ( Session::getRoutingGauge()->getLayerGauge(i)->getType() == Constant::PinOnly ) ++_pinDepth; @@ -165,8 +165,9 @@ namespace Katabatic { { ltrace(90) << "GCell::~GCell()" << endl; + delete [] _blockages; delete [] _densities; - delete [] _saturateDensities; + //delete [] _saturateDensities; _allocateds--; } @@ -406,7 +407,7 @@ namespace Katabatic { } - void GCell::addBlockage ( unsigned int depth, float length ) + void GCell::addBlockage ( unsigned int depth, DbU::Unit length ) { if ( depth >= _depth ) return; @@ -428,7 +429,7 @@ namespace Katabatic { // } ltrace(300) << "GCell:addBlockage() " << this << " " - << depth << ":" << _blockages[depth] << endl; + << depth << ":" << DbU::getValueString(_blockages[depth]) << endl; } @@ -556,13 +557,9 @@ namespace Katabatic { DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/; DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/; DbU::Unit uLengths1 [ _depth ]; - float fLengths1 [ _depth ]; - float fLengths2 [ _depth ]; + DbU::Unit uLengths2 [ _depth ]; - for ( size_t i=0 ; i<_depth ; i++ ) { - fLengths1[i] = 0.0; - fLengths2[i] = 0.0; - } + for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] = 0; // Compute wirelength associated to contacts (in DbU::Unit converted to float). set processeds; @@ -572,29 +569,13 @@ namespace Katabatic { for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0; (*it)->getLengths ( uLengths1, processeds ); for ( size_t i=0 ; i<_depth ; i++ ) { - fLengths1[i] += (float)uLengths1[i]; switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { - case Constant::Horizontal: fLengths2[i] += (float)(uLengths1[i]+hpenalty); break; - case Constant::Vertical: fLengths2[i] += (float)(uLengths1[i]+vpenalty); break; + case Constant::Horizontal: uLengths2[i] += uLengths1[i]+hpenalty; break; + case Constant::Vertical: uLengths2[i] += uLengths1[i]+vpenalty; break; } } } - // Transform the wirelength in density (divide by track length, one - // occupied track count for "one"). - for ( size_t i=0 ; i<_depth ; i++ ) { - switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { - case Constant::Horizontal: - fLengths1[i] /= (float)_box.getWidth (); - fLengths2[i] /= (float)_box.getWidth (); - break; - case Constant::Vertical: - fLengths1[i] /= (float)_box.getHeight(); - fLengths2[i] /= (float)_box.getHeight(); - break; - } - } - // Add the "pass through" horizontal segments. if ( _hsegments.size() ) { const Layer* layer = _hsegments[0]->getLayer(); @@ -602,8 +583,7 @@ namespace Katabatic { size_t count = 0; for ( size_t i=0 ; i<_hsegments.size() ; i++ ) { if ( layer != _hsegments[i]->getLayer() ) { - fLengths1[depth] += (float)count; - fLengths2[depth] += (float)count; + uLengths2[depth] += count * _box.getWidth(); count = 0; layer = _hsegments[i]->getLayer(); @@ -612,8 +592,7 @@ namespace Katabatic { count++; } if ( count ) { - fLengths1[depth] += (float)count; - fLengths2[depth] += (float)count; + uLengths2[depth] += count * _box.getWidth(); } } @@ -624,8 +603,7 @@ namespace Katabatic { size_t count = 0; for ( size_t i=0 ; i<_vsegments.size() ; i++ ) { if ( layer != _vsegments[i]->getLayer() ) { - fLengths1[depth] += (float)count; - fLengths2[depth] += (float)count; + uLengths2[depth] += count * _box.getHeight(); count = 0; layer = _vsegments[i]->getLayer(); @@ -634,46 +612,38 @@ namespace Katabatic { count++; } if ( count ) { - fLengths1[depth] += (float)count; - fLengths2[depth] += (float)count; + uLengths2[depth] += count * _box.getHeight(); } } // Add the blockages. for ( size_t i=0 ; i<_depth ; i++ ) { - fLengths1[i] += _blockages[i]; - fLengths2[i] += _blockages[i]; + uLengths2[i] += _blockages[i]; } // Normalize: 0 < d < 1.0 (divide by H/V capacity). for ( size_t i=0 ; i<_depth ; i++ ) { switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { case Constant::Horizontal: - fLengths1[i] /= hcapacity; - fLengths2[i] /= hcapacity; + _densities[i] = ((float)uLengths2[i]) / ( hcapacity * (float)_box.getWidth() ); break; case Constant::Vertical: - fLengths1[i] /= vcapacity; - fLengths2[i] /= vcapacity; + _densities[i] = ((float)uLengths2[i]) / ( vcapacity * (float)_box.getHeight() ); break; } - if ( fLengths1[i] > 1.0 ) { - _saturated = true; - //fLengths[i] = 1.0; - } - _densities [i] = fLengths1[i]; - _saturateDensities[i] = fLengths2[i]; + if ( _densities[i] >= 1.0 ) _saturated = true; } _cDensity = ( (float)_contacts.size() ) / ccapacity; _invalid = false; for ( size_t i=0 ; i<_depth ; i++ ) { - _densities [i] = roundfp ( _densities [i] ); - _saturateDensities[i] = roundfp ( _saturateDensities[i] ); + _densities[i] = roundfp ( _densities [i] ); } _cDensity = roundfp (_cDensity ); + ltrace(200) << "updateDensity: " << this << endl; + checkDensity (); #if defined(CHECK_DETERMINISM) @@ -683,8 +653,6 @@ namespace Katabatic { << " " << setprecision(9) << gdensity << endl; #endif - //cerr << "updateDensity() " << this << getVectorString(_densities,_depth) << endl; - return ( _saturated ) ? 1 : 0 ; } @@ -693,19 +661,38 @@ namespace Katabatic { { if ( _invalid ) const_cast(this)->updateDensity (); - if ( !Session::getDemoMode() && Session::getWarnGCellOverload() ) { + if ( not Session::getDemoMode() and Session::getWarnGCellOverload() ) { for ( size_t i=0 ; i<_depth ; i++ ) { if ( _densities[i] > 1.0 ) { - cerr << Warning("%s @%dx%d overloaded in %s (M2:%.2f M3:%.2f,%.2f M4:%.2f M5:%.2f)" + cerr << Warning("%s @%dx%d overloaded in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)" ,_getString().c_str() ,getColumn() ,getRow() ,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str() - ,_densities[1] - ,_densities[2] - ,_blockages[2] - ,_densities[3] - ,_densities[4] + ,_densities[1] // M2 + ,_densities[2] // M3 + //,_blockages[2] // M4 + ,_densities[3] // M5 + ,_densities[4] // M6 + ) + << endl; + } + } + for ( size_t i=3 ; i<_depth ; i+=2 ) { + if ( (_densities[i] < 0.3) and (_densities[i-2] < 0.3) ) continue; + + float balance = _densities[i] / (_densities[i-2]+0.001 ); + if ( (balance > 3) or (balance < .33) ) { + cerr << Warning("%s @%dx%d unbalanced in %s (M2:%.2f M3:%.2f M4:%.2f M5:%.2f)" + ,_getString().c_str() + ,getColumn() + ,getRow() + ,getString(Session::getRoutingGauge()->getRoutingLayer(i)->getName()).c_str() + ,_densities[1] // M2 + ,_densities[2] // M3 + //,_blockages[2] // M4 + ,_densities[3] // M5 + ,_densities[4] // M6 ) << endl; } @@ -738,7 +725,7 @@ namespace Katabatic { ) << endl; AutoSegment* segment; - while ( stepDesaturate ( 1, globalNets, segment, true ) ) { + while ( (_densities[1] > 0.5) and stepDesaturate(1,globalNets,segment,true) ) { ltrace(200) << "Moved up: " << segment << endl; } } @@ -783,12 +770,12 @@ namespace Katabatic { case Constant::Vertical: capacity = getVCapacity(); break; } - ltrace(200) << "| hasFreeTrack [" << getIndex() << "] depth:" << depth << " " + ltrace(200) << " | hasFreeTrack [" << getIndex() << "] depth:" << depth << " " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() - << " " << (_saturateDensities[depth]*capacity) << " vs. " << capacity - << endl; - - return (_saturateDensities[depth]*capacity + 1.0 + reserve <= capacity); + << " " << (_densities[depth]*capacity) << " vs. " << capacity + << " " << this << endl; + + return (_densities[depth]*capacity + 1.0 + reserve <= capacity); } @@ -840,11 +827,11 @@ namespace Katabatic { // return false; // } - // (*isegment)->changeDepth ( depth+2, false, false ); - // moved = (*isegment); + (*isegment)->changeDepth ( depth+2, false, false ); + moved = (*isegment); - (*isegment)->shearUp ( this, moved, 0.5, AutoSegment::AllowTerminal ); - updateDensity (); + //(*isegment)->shearUp ( this, moved, 0.5, AutoSegment::AllowTerminal ); + //updateDensity (); //cmess2 << " - GCell [" << getIndex() << "] @" << getColumn() << "x" << getRow() // << ":" << setprecision(4) << density @@ -853,7 +840,60 @@ namespace Katabatic { // << " displaced:" << (*isegment) << "]." // << endl; - if ( moved ) return true; + if ( moved ) { + // cerr << "Desaturating: " << _densities[depth] << " > " << Session::getSaturateRatio() << " " + // << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << " " + // << this << endl; + // cerr << "Moved up: " << moved << endl; + return true; + } + } + + return false; + } + + + bool GCell::stepNetDesaturate ( unsigned int depth, set& globalNets, set& invalidateds ) + { +#if defined(CHECK_DETERMINISM) + cerr << "Order: stepDesaturate [" << getIndex() << "] depth:" << depth << endl; +#endif + ltrace(200) << "stepNetDesaturate() - " << this << endl; + + updateDensity (); + + //if ( not force and not isSaturated(depth) ) return false; + + float capacity; + vector::iterator isegment; + vector::iterator iend; + + switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { + case Constant::Horizontal: + iend = _hsegments.end (); + isegment = _hsegments.begin (); + capacity = getHCapacity (); + break; + case Constant::Vertical: + iend = _vsegments.end (); + isegment = _vsegments.begin (); + capacity = getVCapacity (); + break; + } + + for ( ; (isegment != iend) ; isegment++ ) { + unsigned int segmentDepth = Session::getRoutingGauge()->getLayerDepth((*isegment)->getLayer()); + + if ( segmentDepth < depth ) continue; + if ( segmentDepth > depth ) break; + +#if defined(CHECK_DETERMINISM) + cerr << "Order: Move up " << (*isegment) << endl; +#endif + + //cerr << " Seed segment: " << *isegment << endl; + if ( getGCellGrid()->getKatabatic()->_moveUpNetTrunk(*isegment,globalNets,invalidateds) ) + return true; } return false; @@ -1047,12 +1087,12 @@ namespace Katabatic { record->add ( getSlot ( s.str(), &_densities[depth] ) ); } - for ( size_t depth=0 ; depth<_depth ; ++depth ) { - ostringstream s; - const Layer* layer = rg->getRoutingLayer(depth); - s << "_saturateDensities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; - record->add ( getSlot ( s.str(), &_saturateDensities[depth] ) ); - } + // for ( size_t depth=0 ; depth<_depth ; ++depth ) { + // ostringstream s; + // const Layer* layer = rg->getRoutingLayer(depth); + // s << "_saturateDensities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; + // record->add ( getSlot ( s.str(), &_saturateDensities[depth] ) ); + // } return record; } diff --git a/katabatic/src/KatabaticEngine.cpp b/katabatic/src/KatabaticEngine.cpp index cbe2130a..1c5e95bf 100644 --- a/katabatic/src/KatabaticEngine.cpp +++ b/katabatic/src/KatabaticEngine.cpp @@ -588,7 +588,7 @@ namespace Katabatic { if ( seedSegment ) unexploreds.push_back ( seedSegment ); } } - sort ( unexploreds.begin(), unexploreds.end(), AutoSegment::CompareCanonical() ); + sort ( unexploreds.begin(), unexploreds.end(), AutoSegment::CompareId() ); for ( size_t i=0 ; ibase() << " " << aligneds[0] << endl; for ( size_t j=1 ; j exploredSegments; - vector unexploreds; - vector aligneds; - - forEach ( Component*, icomponent, net->getComponents() ) { - Segment* segment = dynamic_cast(*icomponent); - if ( segment ) { - AutoSegment* seedSegment = Session::lookup ( segment ); - if ( seedSegment ) - unexploreds.push_back ( seedSegment ); - } - } - sort ( unexploreds.begin(), unexploreds.end(), AutoSegment::CompareCanonical() ); - - for ( size_t i=0 ; igetSegment()) == exploredSegments.end() ) { - ltrace(99) << "New chunk from: " << (void*)seedSegment->base() << ":" << seedSegment << endl; - aligneds.push_back ( seedSegment ); - - bool isCanonicalLocal = seedSegment->isLocal(); - forEach ( AutoSegment*, collapsed, seedSegment->getCollapseds() ) { - ltrace(99) << "Aligned: " << (void*)collapsed->base() << ":" << *collapsed << endl; - aligneds.push_back ( *collapsed ); - exploredSegments.insert ( collapsed->getSegment() ); - - if ( collapsed->isGlobal() ) isCanonicalLocal = false; - } - - ltracein(99); - sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareCanonical() ); - - aligneds[0]->setCanonical ( true ); - aligneds[0]->setCanonicalLocal ( isCanonicalLocal ); - ltrace(99) << "Canonical: " << (void*)aligneds[0]->base() << ":" << aligneds[0] << endl; - - for ( size_t j=1 ; jsetCanonical ( false ); - ltrace(99) << "Secondary: " << (void*)(aligneds[j]->base()) << ":" << aligneds[j] << endl; - } - - ltrace(159) << "Align on " << aligneds[0] - << " " << DbU::getLambda(aligneds[0]->getAxis()) << endl; - aligneds[0]->setAxis ( aligneds[0]->getAxis(), Realignate|AxisSet ); - aligneds.clear (); - ltraceout(99); - } - } - - ltraceout(99); - - DebugSession::close (); - } - - void KatabaticEngine::_computeNetTerminals ( Net* net ) { DebugSession::open ( net, 88 ); @@ -866,7 +801,7 @@ namespace Katabatic { segments.push_back ( autoSegment ); } - sort ( segments.begin(), segments.end(), AutoSegment::CompareCanonical() ); + sort ( segments.begin(), segments.end(), AutoSegment::CompareId() ); Interval constraints; for ( size_t i=0 ; igetRoutingLayer(depth)->getName() << endl; //vector gcells = *(_gcellGrid->getGCellVector()); + //vector invalidateds; DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) ); - vector invalidateds; + set invalidateds; bool optimized = true; while ( optimized ) { @@ -128,20 +129,27 @@ namespace Katabatic { break; } - ltrace(190) << "step desaturate: @ " << i << " " << *igcell << endl; + //ltrace(190) << "step desaturate: @ " << i << " " << *igcell << endl; - AutoSegment* segment = NULL; - optimized = (*igcell)->stepDesaturate ( depth, globalNets, segment ); + // AutoSegment* segment = NULL; + // optimized = (*igcell)->stepDesaturate ( depth, globalNets, segment ); - if ( segment ) { - ++total; ++globals; - segment->getGCells ( invalidateds ); - for ( size_t j=0 ; jgetGCells ( invalidateds ); + // for ( size_t j=0 ; jstepNetDesaturate ( depth, globalNets, invalidateds ); + if ( optimized ) { + for ( set::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) { + queue.invalidate ( *igcell ); } + break; } - - if ( optimized ) break; } } } @@ -188,7 +196,7 @@ namespace Katabatic { } - void KatabaticEngine::_layerAssignByTrunk ( Net* net, unsigned long& total, unsigned long& global, set& globalNets ) + void KatabaticEngine::_layerAssignByTrunk ( Net* net, set& globalNets, unsigned long& total, unsigned long& global ) { DebugSession::open ( net, 90 ); @@ -243,7 +251,88 @@ namespace Katabatic { NetSet::iterator inet = _routingNets.begin(); for ( ; inet != _routingNets.end() ; ++inet ) - _layerAssignByTrunk ( *inet, total, global, globalNets ); + _layerAssignByTrunk ( *inet, globalNets, total, global ); + } + + + bool KatabaticEngine::_moveUpNetTrunk ( AutoSegment* seed, set& globalNets, set& invalidateds ) + { + Net* net = seed->getNet(); + DebugSession::open ( net, 90 ); + + ltrace(100) << "_moveUpNetTrunk() - " << seed << endl; + + if ( not seed->canMoveUp(2.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) { + DebugSession::close (); + return false; + } + ltracein(100); + + globalNets.insert ( net ); + + vector globals; + vector locals; + + forEach ( Segment*, isegment, net->getSegments() ) { + AutoSegment* autoSegment = Session::lookup ( *isegment ); + + if ( not autoSegment ) continue; + if ( autoSegment->isLocal() ) { + if ( autoSegment->isTerminal() ) continue; + locals.push_back ( autoSegment ); + } else { + // Ugly: Hard-coded GCell side. + if ( (autoSegment->getLength() < DbU::lambda(150.0)) and (autoSegment != seed) ) + locals.push_back ( autoSegment ); + else + globals.push_back ( autoSegment ); + } + } + + sort ( globals.begin(), globals.end(), AutoSegment::CompareId() ); + sort ( locals.begin(), locals.end(), AutoSegment::CompareId() ); + + for ( size_t i=0 ; icanMoveUp(2.0,AutoSegment::Propagate|AutoSegment::AllowTerminal) ) { + unsigned int depth = Session::getRoutingGauge()->getLayerDepth(globals[i]->getLayer()); + globals[i]->changeDepth ( depth+2, true, false ); + + ltrace(100) << " | Trunk move up G:" << globals[i] << endl; + + vector gcells; + globals[i]->getGCells ( gcells ); + for ( size_t j=0 ; jcanPivotUp(2.0,AutoSegment::Propagate|AutoSegment::IgnoreContact) ) { + if ( locals[i]->canPivotUp(2.0,AutoSegment::Propagate) ) { + unsigned int depth = Session::getRoutingGauge()->getLayerDepth(locals[i]->getLayer()); + locals[i]->changeDepth ( depth+2, true, false ); + + ltrace(100) << " | Trunk move up L:" << locals[i] << endl; + + vector gcells; + locals[i]->getGCells ( gcells ); + for ( size_t j=0 ; jsetVAlignate ( true ); + } + if ( _topology & (GLOBAL_VERTICAL|GLOBAL_FORK) ) { ltrace(99) << "Global Vertical/Global fork " << _south << endl; @@ -2173,11 +2178,8 @@ namespace { , false ); segment->setStrap ( true ); - - if ( direction == Constant::Vertical ) { - if ( !_south ) _northEastContact->setVAlignate ( true ); - else _southWestContact->setVAlignate ( true ); - } + _northEastContact->setVAlignate ( true ); + _southWestContact->setVAlignate ( true ); } } diff --git a/katabatic/src/NetOptimals.cpp b/katabatic/src/NetOptimals.cpp index 2bcfbea1..4446df8a 100644 --- a/katabatic/src/NetOptimals.cpp +++ b/katabatic/src/NetOptimals.cpp @@ -63,7 +63,7 @@ namespace Katabatic { if ( !autoSegment ) continue; segments.push_back ( autoSegment ); } - sort ( segments.begin(), segments.end(), AutoSegment::CompareCanonical() ); + sort ( segments.begin(), segments.end(), AutoSegment::CompareId() ); set processeds; for ( size_t i=0 ; i processeds; for ( size_t i=0 ; i exploredSegments; vector aligneds; - sort ( _autoSegments.begin(), _autoSegments.end(), AutoSegment::CompareCanonical() ); + sort ( _autoSegments.begin(), _autoSegments.end(), AutoSegment::CompareId() ); for ( size_t i=0 ; i<_autoSegments.size() ; i++ ) { AutoSegment* seedSegment = _autoSegments[i]; @@ -207,10 +207,10 @@ namespace Katabatic { } ltracein(110); - sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareCanonical() ); + sort ( aligneds.begin(), aligneds.end(), AutoSegment::CompareId() ); if ( aligneds.size() > 1 ) { - if ( not AutoSegment::CompareCanonical() ( aligneds[0], aligneds[1] ) ) { + if ( not AutoSegment::CompareId() ( aligneds[0], aligneds[1] ) ) { cerr << "Ambiguous canonization: " << aligneds[0]->base() << endl; cerr << "Ambiguous canonization: " << aligneds[1]->base() << endl; } @@ -221,6 +221,11 @@ namespace Katabatic { ltrace(110) << "Canonical: " << aligneds[0] << endl; for ( size_t j=1 ; jisCanonical() ) { + cerr << Error("Session::_canonize(): On %s\n" + " Segment is no longer the canonical one, this must not happens." + ,getString(aligneds[j]).c_str()) << endl; + } aligneds[j]->setCanonical ( false ); ltrace(110) << "Secondary: " << aligneds[j] << endl; } diff --git a/katabatic/src/katabatic/AutoContact.h b/katabatic/src/katabatic/AutoContact.h index c39a5c83..c5fffc83 100644 --- a/katabatic/src/katabatic/AutoContact.h +++ b/katabatic/src/katabatic/AutoContact.h @@ -178,6 +178,7 @@ namespace Katabatic { virtual Box getBoundingBox () const; inline GCell* getGCell () const; unsigned int getMinDepth () const; + unsigned int getMaxDepth () const; bool canDestroy ( bool error=false ) const; inline bool isInvalidated () const; inline bool isCorner () const; diff --git a/katabatic/src/katabatic/AutoSegment.h b/katabatic/src/katabatic/AutoSegment.h index 353601bf..c163648a 100644 --- a/katabatic/src/katabatic/AutoSegment.h +++ b/katabatic/src/katabatic/AutoSegment.h @@ -86,17 +86,17 @@ namespace Katabatic { , ParallelOrExpanded = (1<<2) , ParallelAndLayerChange = (1<<3) }; - enum Flags { Propagate=0x1, AllowLocal=0x2, AllowTerminal=0x4 }; + enum Flags { Propagate =0x1 + , AllowLocal =0x2 + , AllowTerminal=0x4 + , IgnoreContact=0x8 + }; public: struct CompareId : public binary_function { inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const; }; - public: - struct CompareCanonical : public binary_function { - bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const; - }; public: struct CompareByDepthLength : public binary_function { bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; @@ -198,7 +198,9 @@ namespace Katabatic { bool canDesalignate (); virtual bool canDesalignate ( AutoContact* ) const = 0; bool canMoveUp ( float reserve=0.0, unsigned int flags=0 ); - bool canPivotUp ( bool propagate=false, float reserve=0.0 ); + //bool canPivotUp ( bool propagate=false, float reserve=0.0 ); + bool canPivotUp ( float reserve=0.0, unsigned int flags=0 ); + bool canPivotDown ( bool propagate=false, float reserve=0.0 ); bool canSlacken ( bool propagate=false ); virtual bool _canSlacken () const = 0; bool canGoOutsideGCell () const; @@ -212,6 +214,7 @@ namespace Katabatic { AutoContact* getOppositeAnchor ( AutoContact* ) const; size_t getAlignedContacts ( map& ); size_t getPerpandicularsBound ( set& ); + inline AutoSegment* getParent () const; inline DbU::Unit getAxis () const; virtual DbU::Unit getSourceU () const = 0; virtual DbU::Unit getTargetU () const = 0; @@ -278,6 +281,7 @@ namespace Katabatic { void _computeTerminal ( Segment* ); virtual void _computeTerminal () = 0; virtual bool checkInvalidated () const; + inline void setParent ( AutoSegment* ); AutoSegment* canonize (); void changeDepth ( unsigned int depth , bool propagate =false @@ -285,6 +289,7 @@ namespace Katabatic { ); void _changeDepth ( unsigned int depth, bool withNeighbors ); bool moveUp ( unsigned int flags=0 ); + bool moveDown ( unsigned int flags=0 ); virtual void moveULeft () = 0; virtual void moveURight () = 0; void slacken ( bool propagate=false ); @@ -334,6 +339,7 @@ namespace Katabatic { DbU::Unit _sourcePosition; DbU::Unit _targetPosition; Interval _userConstraints; + AutoSegment* _parent; // Internal: Constructors & Destructors. protected: @@ -369,6 +375,7 @@ namespace Katabatic { inline Contact* AutoSegment::getSource () const { return static_cast(getSegment()->getSource()); } inline Contact* AutoSegment::getTarget () const { return static_cast(getSegment()->getTarget()); } inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return getSegment()->getOppositeAnchor(anchor); }; + inline AutoSegment* AutoSegment::getParent () const { return _parent; } inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; } inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; } inline DbU::Unit AutoSegment::getSourceX () const { return getSegment()->getSourceX(); } @@ -423,6 +430,14 @@ namespace Katabatic { inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); } inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); } + inline void AutoSegment::setParent ( AutoSegment* parent ) + { + if ( parent == this ) { + cerr << "Parentage Looping: " << parent->_getString() << endl; + } + _parent = parent; + } + inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const { return lhs->getId() < rhs->getId(); } diff --git a/katabatic/src/katabatic/GCell.h b/katabatic/src/katabatic/GCell.h index dc245006..9beb5ed4 100644 --- a/katabatic/src/katabatic/GCell.h +++ b/katabatic/src/katabatic/GCell.h @@ -134,7 +134,7 @@ namespace Katabatic { inline float getCDensity ( bool update=true ) const; inline float getDensity ( unsigned int depth, bool update=true ) const; float getDensity ( bool update=true ) const; - inline float getBlockage ( unsigned int depth ) const; + inline DbU::Unit getBlockage ( unsigned int depth ) const; float getStiffness () const; inline vector* getVSegments (); inline vector* getHSegments (); @@ -150,7 +150,7 @@ namespace Katabatic { size_t checkDensity () const; bool checkEdgeSaturation ( float threshold ) const; // Modifiers. - void addBlockage ( unsigned int depth, float ); + void addBlockage ( unsigned int depth, DbU::Unit ); inline void addVSegment ( AutoSegment* ); inline void addHSegment ( AutoSegment* ); inline void addContact ( AutoContact* ); @@ -162,6 +162,7 @@ namespace Katabatic { inline void updateKey ( unsigned int depth ); void desaturate ( unsigned int depth, set& ); bool stepDesaturate ( unsigned int depth, set&, AutoSegment*& moved, bool force=false ); + bool stepNetDesaturate ( unsigned int depth, set&, set& invalidateds ); void rpDesaturate ( set& ); inline void invalidate (); // Inspector Management. @@ -184,10 +185,10 @@ namespace Katabatic { Box _box; size_t _depth; size_t _pinDepth; - float* _blockages; + DbU::Unit* _blockages; float _cDensity; float* _densities; - float* _saturateDensities; + //float* _saturateDensities; bool _saturated; bool _invalid; Key _key; @@ -244,8 +245,8 @@ namespace Katabatic { inline float GCell::getDensity ( unsigned int depth, bool update ) const { if (_invalid and update) const_cast(this)->updateDensity(); return _densities[depth]; } - inline float GCell::getBlockage ( unsigned int depth ) const - { return (depth<_depth) ? _blockages[depth] : 0.0; } + inline DbU::Unit GCell::getBlockage ( unsigned int depth ) const + { return (depth<_depth) ? _blockages[depth] : 0; } inline void GCell::addVSegment ( AutoSegment* segment ) { invalidate(); _vsegments.push_back(segment); } diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index 86633ae9..7f8a71c7 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -191,12 +191,12 @@ namespace Katabatic { void _loadGrByNet (); void _loadNetGlobalRouting ( Net* ); void _alignate ( Net* ); - void _canonize ( Net* ); void _desaturate ( unsigned int depth, set&, unsigned long& total, unsigned long& globals ); void _layerAssignByLength ( unsigned long& total, unsigned long& global, set& ); - void _layerAssignByLength ( Net* , unsigned long& total, unsigned long& global, set& ); + void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set& ); void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& ); - void _layerAssignByTrunk ( Net* , unsigned long& total, unsigned long& global, set& ); + void _layerAssignByTrunk ( Net*, set&, unsigned long& total, unsigned long& global ); + bool _moveUpNetTrunk ( AutoSegment*, set& globalNets, set& invalidateds ); void _splitContactsOfNet ( Net* ); void _collapseNet ( const Name& , unsigned int depth=1 ); void _collapseNet ( Net* , unsigned int depth=1 );