diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index f56c29ec..ee75f16a 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -29,6 +29,7 @@ #include "hurricane/UpdateSession.h" #include "crlcore/RoutingGauge.h" #include "crlcore/Measures.h" +#include "crlcore/Histogram.h" #include "anabatic/GCell.h" #include "anabatic/AutoContactTerminal.h" #include "anabatic/NetBuilderM2.h" @@ -145,6 +146,7 @@ namespace Anabatic { using CRL::RoutingLayerGauge; using CRL::addMeasure; using CRL::getMeasure; + using CRL::Histogram; // ------------------------------------------------------------------- @@ -489,10 +491,18 @@ namespace Anabatic { void AnabaticEngine::setupNetDatas () { + Histogram netHistogram ( 0.0, 1.0, 1 ); + netHistogram.setTitle ( "RoutingPads", 0 ); + netHistogram.setColor ( "green" , 0 ); + netHistogram.setIndent( " " , 0 ); + size_t oindex = _netOrdering.size(); for ( Net* net : _cell->getNets() ) { if (_netDatas.find(net->getId()) != _netDatas.end()) continue; - _netOrdering.push_back( new NetData(net) ); + NetData* data = new NetData( net ); + _netOrdering.push_back( data ); + + netHistogram.addSample( (float)data->getRpCount(), 0 ); } for ( ; oindex < _netOrdering.size() ; ++oindex ) { @@ -501,6 +511,9 @@ namespace Anabatic { } sort( _netOrdering.begin(), _netOrdering.end(), SparsityOrder() ); + + cmess2 << " o Nets Histogram." << endl; + cmess2 << netHistogram.toString(0) << endl; } diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index 77b23abd..1ae6a1d8 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -274,11 +274,11 @@ namespace Anabatic { void AutoContact::invalidate ( Flags flags ) { + if (flags & Flags::Topology ) setFlags( CntInvalidatedCache ); if (not isInvalidated()) { cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl; cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl; setFlags( CntInvalidated ); - if (flags & Flags::Topology ) setFlags( CntInvalidatedCache ); Session::invalidate( this ); _invalidate( flags ); @@ -554,6 +554,9 @@ namespace Anabatic { void AutoContact::setLayerAndWidth ( size_t delta, size_t depth ) { + cdebug_log(145,1) << "AutoContact::setLayerAndWidth() " << this << endl; + cdebug_log(145,0) << "delta:" << delta << " depth:" << depth << endl; + if (delta == 0) { setLayer( Session::getRoutingLayer(depth) ); setSizes( Session::getWireWidth (depth) @@ -563,6 +566,8 @@ namespace Anabatic { setSizes( Session::getViaWidth (depth) , Session::getViaWidth (depth) ); } + + cdebug_tabw(145,-1); } diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index c93ea0fa..e9483699 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -337,7 +337,7 @@ namespace Anabatic { void AutoContactTerminal::cacheDetach ( AutoSegment* segment ) { if (_segment == segment) { - _segment->unsetFlags( AutoSegment::SegAxisSet ); + //_segment->unsetFlags( AutoSegment::SegAxisSet ); _segment = NULL; setFlags( CntInvalidatedCache ); unsetFlags( CntDrag ); diff --git a/anabatic/src/AutoContactTurn.cpp b/anabatic/src/AutoContactTurn.cpp index 1d502e6f..106d14a9 100644 --- a/anabatic/src/AutoContactTurn.cpp +++ b/anabatic/src/AutoContactTurn.cpp @@ -239,7 +239,7 @@ namespace Anabatic { RoutingGauge* rg = Session::getRoutingGauge(); size_t depthH1 = rg->getLayerDepth( getHorizontal1()->getLayer() ); size_t depthV1 = rg->getLayerDepth( getVertical1 ()->getLayer() ); - size_t depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1; + size_t depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1; size_t delta = abssub ( depthH1, depthV1 ); unsetFlags( CntWeakTerminal ); @@ -247,7 +247,7 @@ namespace Anabatic { showTopologyError( "Sheared Turn, layer delta exceed 3." ); setFlags( CntBadTopology ); } else { - if (delta == 3) { + if (delta > 1) { if (_horizontal1->isInvalidatedLayer()) { //_horizontal1 = static_cast( _horizontal1->makeDogleg(this) ); _horizontal1->makeDogleg(this); @@ -259,7 +259,7 @@ namespace Anabatic { } depthH1 = rg->getLayerDepth( _horizontal1->getLayer() ); depthV1 = rg->getLayerDepth( _vertical1->getLayer() ); - depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1; + depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1; delta = abssub ( depthH1, depthV1 ); } diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index c1744fab..1119b791 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -831,27 +831,62 @@ namespace Anabatic { segment2->setFlags( (isSlackened()?SegSlackened:0) ); Session::dogleg( segment2 ); - if (autoSource->isTerminal()) { - segment1->setFlags( SegWeakTerminal1 ); - segment2->setFlags( SegWeakTerminal1 ); + if (autoSource->isTerminal() and autoTarget->isTerminal()) { + segment1->setRpDistance( 1 ); + segment2->setRpDistance( 0 ); + dlContact1->setFlags ( CntWeakTerminal ); + dlContact2->setFlags ( CntWeakTerminal ); + + if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget ); + if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource ); + } else if (autoSource->isTerminal()) { + segment1->setRpDistance( 1 ); + segment2->setRpDistance( 2 ); + autoTarget->unsetFlags( CntWeakTerminal ); dlContact1->setFlags ( CntWeakTerminal ); - if (autoTarget->getGCell() == doglegGCell) - dlContact1->migrateConstraintBox( autoTarget ); + if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget ); } else if (autoTarget->isTerminal()) { + segment2->setRpDistance( 0 ); + segment1->setRpDistance( 1 ); + setRpDistance( 2 ); + unsetFlags( SegTargetTerminal ); setFlags( SegWeakTerminal1 ); - segment1->setFlags( SegWeakTerminal1 ); - segment2->setFlags( SegTargetTerminal ); autoSource->unsetFlags( CntWeakTerminal ); dlContact2->setFlags ( CntWeakTerminal ); - if (autoSource->getGCell() == doglegGCell) - dlContact2->migrateConstraintBox( autoSource ); - } else if (isWeakTerminal()) { + if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource ); + } else if (isWeakTerminal()) { segment1->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 ); + segment1->setRpDistance( getRpDistance() ); + segment2->setRpDistance( getRpDistance() ); + } else { + segment1->setRpDistance( getRpDistance() ); + segment2->setRpDistance( getRpDistance() ); } + // if (autoSource->isTerminal()) { + // segment1->setFlags( SegWeakTerminal1 ); + // segment2->setFlags( SegWeakTerminal1 ); + // autoTarget->unsetFlags( CntWeakTerminal ); + // dlContact1->setFlags ( CntWeakTerminal ); + // if (autoTarget->getGCell() == doglegGCell) + // dlContact1->migrateConstraintBox( autoTarget ); + // } else if (autoTarget->isTerminal()) { + // unsetFlags( SegTargetTerminal ); + // setFlags( SegWeakTerminal1 ); + // segment1->setFlags( SegWeakTerminal1 ); + // segment2->setFlags( SegTargetTerminal ); + // autoSource->unsetFlags( CntWeakTerminal ); + // dlContact2->setFlags ( CntWeakTerminal ); + // if (autoSource->getGCell() == doglegGCell) + // dlContact2->migrateConstraintBox( autoSource ); + // } else if (isWeakTerminal()) { + // segment1->setFlags( SegWeakTerminal1 ); + // segment2->setFlags( SegWeakTerminal1 ); + // } + if (isAnalog()) { segment1->setFlags( SegAnalog ); segment2->setFlags( SegAnalog ); @@ -871,8 +906,11 @@ namespace Anabatic { updateNativeConstraints(); segment2->updateNativeConstraints(); + if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntVDogleg ); + if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntVDogleg ); + if (autoTarget->canDrag() and not autoSource->canDrag()) { - if (not autoTarget->getGCell()->isDevice()) { + if (not autoTarget->getGCell()->isDevice() and (segment1->getGCell() == autoTarget->getGCell())) { Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal); segment1->mergeUserConstraints( dragConstraints ); diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index e30d82c4..9d9b9962 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -472,6 +472,7 @@ namespace Anabatic { , _optimalMin (0) , _optimalMax (0) , _reduceds (0) + , _rpDistance (15) , _sourcePosition (0) , _targetPosition (0) , _userConstraints (false) @@ -687,11 +688,11 @@ namespace Anabatic { bool AutoSegment::isStrongTerminal ( Flags flags ) const { - if (_flags & SegStrongTerminal) return true; + if (isTerminal()) return true; if ((flags & Flags::Propagate) and not isNotAligned()) { for ( AutoSegment* segment : const_cast(this)->getAligneds() ) { - if (segment->_flags & SegStrongTerminal) return true; + if (segment->isTerminal()) return true; } } return false; @@ -761,8 +762,8 @@ namespace Anabatic { { cdebug_log(145,0) << "AutoSegment::getCanonical() - " << this << endl; - min = getSourcePosition (); - max = getTargetPosition (); + min = getSourcePosition(); + max = getTargetPosition(); if (max < min) swap( min, max ); @@ -775,14 +776,14 @@ namespace Anabatic { DbU::Unit collapsedMax; if (not isNotAligned()) { - forEach( AutoSegment*, isegment, getAligneds() ) { - if (isegment->isCanonical()) { - canonical = *isegment; + for ( AutoSegment* segment : getAligneds() ) { + if (segment->isCanonical()) { + canonical = segment; canonicals++; } - collapsedMin = isegment->getSourcePosition(); - collapsedMax = isegment->getTargetPosition(); + collapsedMin = segment->getSourcePosition(); + collapsedMax = segment->getTargetPosition(); if (collapsedMax < collapsedMin) swap( collapsedMin, collapsedMax ); if (collapsedMin < min) min = collapsedMin; if (collapsedMax > max) max = collapsedMax; @@ -799,8 +800,8 @@ namespace Anabatic { int count = 0; cerr << " " << count++ << ": " << this << endl; - forEach( AutoSegment*, isegment, getAligneds() ) - cerr << " " << count++ << ": " << *isegment << endl; + for ( AutoSegment* segment : getAligneds() ) + cerr << " " << count++ << ": " << segment << endl; } } @@ -1036,6 +1037,10 @@ namespace Anabatic { cdebug_log(149,1) << "toOptimalAxis() " << this << endl; if (not isCanonical()) { cdebug_tabw(149,-1); return false; } + if (not isUnsetAxis()) { + cdebug_tabw(149,-1); + return toConstraintAxis( flags ); + } DbU::Unit constraintMin; DbU::Unit constraintMax; @@ -1539,23 +1544,35 @@ namespace Anabatic { bool AutoSegment::canReduce () const { - if (isGlobal() or isDrag()) return false; + cdebug_log(159,0) << "AutoSegment::canReduce():" << this << endl; + cdebug_log(159,0) << " _reduceds:" << _reduceds << endl; + + if (isGlobal() or isDrag() or isFixed()) return false; if (not isSpinTopOrBottom()) return false; if (_reduceds) return false; AutoContact* source = getAutoSource(); AutoContact* target = getAutoTarget(); - if (not source->isTurn() or not target->isTurn()) return false; + cdebug_log(159,0) << " source:" << source->isHTee() << "+" << source->isVTee() << endl; + cdebug_log(159,0) << " target:" << target->isHTee() << "+" << target->isVTee() << endl; + + if ( ((source->isHTee() or target->isHTee()) and isHorizontal()) + or ((source->isVTee() or target->isVTee()) and isVertical ()) ) return false; + + // if ( source->isHTee() or source->isVTee() + // or target->isHTee() or target->isVTee() ) return false; unsigned int perpandicularDepth = getDepth(); - if (isSpinBottom()) --perpandicularDepth; - else if (isSpinTop()) { + if (isSpinBottom()) { + if (perpandicularDepth > 0) --perpandicularDepth; + } else if (isSpinTop()) { ++perpandicularDepth; if (perpandicularDepth >= Session::getDepth()) return false; } else return false; + cdebug_log(159,0) << " length:" << DbU::getValueString(getLength()) << endl; if (getLength() >= (Session::getPitch(perpandicularDepth) * 2)) return false; return true; @@ -1570,8 +1587,17 @@ namespace Anabatic { AutoContact* target = getAutoTarget(); _flags |= SegIsReduced; - source->getPerpandicular( this )->incReduceds(); - target->getPerpandicular( this )->incReduceds(); + for ( AutoSegment* perpandicular : source->getAutoSegments() ) { + if (perpandicular == this) continue; + perpandicular->incReduceds(); + } + for ( AutoSegment* perpandicular : target->getAutoSegments() ) { + if (perpandicular == this) continue; + perpandicular->incReduceds(); + } + + // if (not source->isTerminal()) source->getPerpandicular( this )->incReduceds(); + // if (not target->isTerminal()) target->getPerpandicular( this )->incReduceds(); return true; } @@ -1598,8 +1624,16 @@ namespace Anabatic { AutoContact* target = getAutoTarget(); _flags &= ~SegIsReduced; - source->getPerpandicular( this )->decReduceds(); - target->getPerpandicular( this )->decReduceds(); + //if (not source->isTerminal()) source->getPerpandicular( this )->decReduceds(); + //if (not target->isTerminal()) target->getPerpandicular( this )->decReduceds(); + for ( AutoSegment* perpandicular : source->getAutoSegments() ) { + if (perpandicular == this) continue; + perpandicular->decReduceds(); + } + for ( AutoSegment* perpandicular : target->getAutoSegments() ) { + if (perpandicular == this) continue; + perpandicular->decReduceds(); + } return true; } @@ -1607,6 +1641,8 @@ namespace Anabatic { void AutoSegment::changeDepth ( unsigned int depth, Flags flags ) { + DebugSession::open( getNet(), 145, 150 ); + cdebug_log(149,1) << "changeDepth() " << depth << " - " << this << endl; Session::invalidate( getNet() ); @@ -1620,6 +1656,8 @@ namespace Anabatic { } cdebug_tabw(149,-1); + + DebugSession::close(); } @@ -1632,6 +1670,7 @@ namespace Anabatic { const Layer* newLayer = Session::getRoutingGauge()->getRoutingLayer(depth); if (getLayer() != newLayer) { + cdebug_log(149,0) << "Effective layer change to " << depth << "/" << newLayer << endl; setLayer( depth ); getAutoSource()->invalidate( Flags::Topology|Flags::NoCheckLayer ); getAutoTarget()->invalidate( Flags::Topology|Flags::NoCheckLayer ); @@ -1741,7 +1780,7 @@ namespace Anabatic { cdebug_log(149,0) << "AutoSegment::canPivotUp() - " << flags << " (reserve:" << reserve << ")" << endl; - if ( isLayerChange() or isFixed() ) return false; + if ( isLayerChange() or isFixed() or isUnbreakable() ) return false; if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false; if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false; @@ -1790,7 +1829,7 @@ namespace Anabatic { cdebug_log(149,0) << "AutoSegment::canPivotDown()" << " (reserve:" << reserve << ")" << endl; - if ( isLayerChange() or isFixed() ) return false; + if ( isLayerChange() or isFixed() or isUnbreakable() ) return false; if ( isStrongTerminal() or isLocal() ) return false; size_t depth = Session::getRoutingGauge()->getLayerDepth( getLayer() ); @@ -1840,7 +1879,7 @@ namespace Anabatic { bool nLowDensity = true; bool nLowUpDensity = true; - if ( isLayerChange() or isFixed() ) return false; + if ( isLayerChange() or isFixed() or isUnbreakable() ) return false; if ( isStrongTerminal() and (not (flags & Flags::AllowTerminal)) ) return false; if ( isLocal() and (not (flags & Flags::AllowLocal )) ) return false; @@ -1952,36 +1991,90 @@ namespace Anabatic { { if (not isReduced()) return true; + DebugSession::open( getNet(), 149, 160 ); + cdebug_log(159,1) << "AutoSegment::reduceDoglegLayer(): " << this << endl; + AutoContact* source = getAutoSource(); AutoContact* target = getAutoTarget(); - unsigned int perpandicularDepth = getDepth(); - if (isSpinBottom()) --perpandicularDepth; - if (isSpinTop ()) ++perpandicularDepth; + unsigned int minSourceDepth = Session::getAllowedDepth(); + unsigned int maxSourceDepth = 0; + unsigned int minTargetDepth = Session::getAllowedDepth(); + unsigned int maxTargetDepth = 0; - if (perpandicularDepth == getDepth()) { - cerr << Bug( "AutoSegment::reduceDoglegLayer(): Reduced segment spin is neither top (TT) nor bottom (BB).\n" - " %s" - , getString(this).c_str() ) << endl; - return false; + if (source->isTerminal()) { + unsigned int anchorDepth = Session::getLayerDepth( source->base()->getAnchor()->getLayer() ); + minSourceDepth = std::min( minSourceDepth, anchorDepth ); + maxSourceDepth = std::max( maxSourceDepth, anchorDepth ); + } else { + for ( AutoSegment* perpandicular : source->getAutoSegments() ) { + if (perpandicular == this) continue; + minSourceDepth = std::min( minSourceDepth, perpandicular->getDepth() ); + maxSourceDepth = std::max( maxSourceDepth, perpandicular->getDepth() ); + } + } + if (target->isTerminal()) { + unsigned int anchorDepth = Session::getLayerDepth( target->base()->getAnchor()->getLayer() ); + minTargetDepth = std::min( minTargetDepth, anchorDepth ); + maxTargetDepth = std::max( maxTargetDepth, anchorDepth ); + } else { + for ( AutoSegment* perpandicular : target->getAutoSegments() ) { + if (perpandicular == this) continue; + minTargetDepth = std::min( minTargetDepth, perpandicular->getDepth() ); + maxTargetDepth = std::max( maxTargetDepth, perpandicular->getDepth() ); + } } - const Layer* layer = Session::getRoutingLayer(perpandicularDepth); - DbU::Unit side = Session::getWireWidth (perpandicularDepth); - - source->setLayer( layer ); - target->setLayer( layer ); - setLayer( layer ); - source->setSizes( side, side ); - target->setSizes( side, side ); + cdebug_log(159,0) << "Source span: [" << minSourceDepth << " " << maxSourceDepth << "]" << endl; + cdebug_log(159,0) << "Target span: [" << minTargetDepth << " " << maxTargetDepth << "]" << endl; + if ( (minSourceDepth == maxSourceDepth) + and (minTargetDepth == maxTargetDepth) + and (minTargetDepth == minTargetDepth) ) { + const Layer* layer = Session::getRoutingLayer(minSourceDepth); + DbU::Unit side = Session::getWireWidth (minSourceDepth); + + cdebug_log(159,0) << "Reducing to " << minSourceDepth << " " << layer << endl; + + source->setLayer( layer ); + target->setLayer( layer ); + setLayer( layer ); + source->setSizes( side, side ); + target->setSizes( side, side ); + } + + cdebug_tabw(159,-1); + DebugSession::close(); return true; + + + // if (not source->isTurn() or not target->isTurn()) return true; + + // unsigned int perpandicularDepth = getDepth(); + // if (isSpinBottom()) --perpandicularDepth; + // if (isSpinTop ()) ++perpandicularDepth; + + // if (perpandicularDepth == getDepth()) { + // cerr << Bug( "AutoSegment::reduceDoglegLayer(): Reduced segment spin is neither top (TT) nor bottom (BB).\n" + // " %s" + // , getString(this).c_str() ) << endl; + // return false; + // } + + // const Layer* layer = Session::getRoutingLayer(perpandicularDepth); + // DbU::Unit side = Session::getWireWidth (perpandicularDepth); + + // source->setLayer( layer ); + // target->setLayer( layer ); + // setLayer( layer ); + // source->setSizes( side, side ); + // target->setSizes( side, side ); + + // return true; } #if THIS_IS_DISABLED - - bool AutoSegment::shearUp ( GCell* upGCell, AutoSegment*& movedUp, float reserve, Flags flags ) { cdebug_log(149,0) << "AutoSegment::shearUp() " << this << endl; @@ -2065,11 +2158,11 @@ namespace Anabatic { if (not isNotAligned()) { for ( AutoSegment* segment : getAligneds() ) { if (segment->getSpanU().contains(interval.getVMin())) { - if (segment->isFixed()) return false; + if (segment->isFixed()) return Flags::NoFlags; leftDogleg++; } if (segment->getSpanU().contains(interval.getVMax())) { - if (segment->isFixed()) return 0; + if (segment->isFixed()) return Flags::NoFlags; rightDogleg++; } } @@ -2114,14 +2207,14 @@ namespace Anabatic { cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1] << endl; if (isSource) { - doglegs[ index + 0 ]->setLayer( segmentDepth-2 ); + doglegs[ index + 0 ]->setLayer( std::max((size_t)1,segmentDepth-2) ); doglegs[ index + 1 ]->getAutoSource()->setLayer( rg->getContactLayer(segmentDepth-2) ); doglegs[ index + 1 ]->getAutoTarget()->setLayer( rg->getContactLayer(segmentDepth-1) ); cdebug_log(149,0) << "doglegs[i+0]: " << doglegs[index+0] << endl; cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1]->getAutoSource() << endl; cdebug_log(149,0) << "doglegs[i+1]: " << doglegs[index+1]->getAutoTarget() << endl; } else { - doglegs[ index + 2 ]->setLayer( segmentDepth-2 ); + doglegs[ index + 2 ]->setLayer( std::max((size_t)1,segmentDepth-2) ); doglegs[ index + 1 ]->getAutoTarget()->setLayer( rg->getContactLayer(segmentDepth-2) ); doglegs[ index + 1 ]->getAutoSource()->setLayer( rg->getContactLayer(segmentDepth-1) ); cdebug_log(149,0) << "doglegs[i+2]: " << doglegs[index+2] << endl; @@ -2262,10 +2355,10 @@ namespace Anabatic { } else { cdebug_log(149,0) << "Looking in aligneds." << endl; if (not isNotAligned()) { - forEach ( AutoSegment*, aligned, getAligneds(flags) ) { - cdebug_log(149,0) << "| Try in " << *aligned << endl; + for ( AutoSegment* aligned : getAligneds(flags) ) { + cdebug_log(149,0) << "| Try in " << aligned << endl; if (doglegGCell->getSide(getDirection()).intersect(aligned->getSpanU())) { - cdebug_log(149,0) << "Dogleg in " << *aligned << endl; + cdebug_log(149,0) << "Dogleg in " << aligned << endl; rflags = aligned->_makeDogleg( doglegGCell, flags ); cdebug_tabw(149,-1); return 0; @@ -2312,6 +2405,7 @@ namespace Anabatic { state += isFixedAxis () ? "X": "-"; state += isUnsetAxis () ? "u": "-"; state += isStrap () ? "S": "-"; + state += isUnbreakable () ? "U": "-"; state += isCanonical () ? "C": "-"; state += isGlobal () ? "G": "-"; state += isWeakGlobal () ? "g": "-"; @@ -2341,9 +2435,9 @@ namespace Anabatic { string AutoSegment::_getString () const { - string s = base()->_getString(); - //s.insert ( 1, "id: " ); - //s.insert ( 4, getString(_id) ); + string sdistance = " rpD:" + getString(_rpDistance); + string s = base()->_getString(); + s.insert ( s.size()-1, sdistance ); s.insert ( s.size()-1, _getStringFlags() ); return s; } @@ -2511,6 +2605,19 @@ namespace Anabatic { const Layer* vLayer = Session::getDVerticalLayer(); DbU::Unit vWidth = Session::getDVerticalWidth(); + if (dir & Flags::UseNonPref) { + if (dir & Flags::Vertical) { + cdebug_log(149,0) << "Make vertical in non-preferred direction." << endl; + vLayer = hLayer; + vWidth = hWidth; + } + if (dir & Flags::Horizontal) { + cdebug_log(149,0) << "Make horizontal in non-preferred direction." << endl; + hLayer = vLayer; + hWidth = vWidth; + } + } + const Layer* horizontalLayer = hLayer; DbU::Unit horizontalWidth = hWidth; const Layer* verticalLayer = vLayer; @@ -2581,6 +2688,7 @@ namespace Anabatic { if (wPitch > 1) segment->setFlags( SegWide ); if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag ); + if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref ); return segment; } diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index b5038068..d7ed5bfb 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -741,27 +741,62 @@ namespace Anabatic { segment2->setFlags( (isSlackened()?SegSlackened:0) ); Session::dogleg( segment2 ); - if (isSourceTerminal()) { - segment1->setFlags( SegWeakTerminal1 ); - segment2->setFlags( SegWeakTerminal1 ); + if (autoSource->isTerminal() and autoTarget->isTerminal()) { + segment1->setRpDistance( 1 ); + segment2->setRpDistance( 0 ); + dlContact1->setFlags ( CntWeakTerminal ); + dlContact2->setFlags ( CntWeakTerminal ); + + if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget ); + if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource ); + } else if (autoSource->isTerminal()) { + segment1->setRpDistance( 1 ); + segment2->setRpDistance( 2 ); + autoTarget->unsetFlags( CntWeakTerminal ); dlContact1->setFlags ( CntWeakTerminal ); - if (autoTarget->getGCell() == doglegGCell) - dlContact1->migrateConstraintBox( autoTarget ); - } else if (isTargetTerminal()) { + if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget ); + } else if (autoTarget->isTerminal()) { + segment2->setRpDistance( 0 ); + segment1->setRpDistance( 1 ); + setRpDistance( 2 ); + unsetFlags( SegTargetTerminal ); setFlags( SegWeakTerminal1 ); - segment1->setFlags( SegWeakTerminal1 ); - segment2->setFlags( SegTargetTerminal ); autoSource->unsetFlags( CntWeakTerminal ); dlContact2->setFlags ( CntWeakTerminal ); - if (autoSource->getGCell() == doglegGCell) - dlContact2->migrateConstraintBox( autoSource ); - } else if (isWeakTerminal()) { + if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource ); + } else if (isWeakTerminal()) { segment1->setFlags( SegWeakTerminal1 ); segment2->setFlags( SegWeakTerminal1 ); + segment1->setRpDistance( getRpDistance() ); + segment2->setRpDistance( getRpDistance() ); + } else { + segment1->setRpDistance( getRpDistance() ); + segment2->setRpDistance( getRpDistance() ); } + // if (isSourceTerminal()) { + // segment1->setFlags( SegWeakTerminal1 ); + // segment2->setFlags( SegWeakTerminal1 ); + // autoTarget->unsetFlags( CntWeakTerminal ); + // dlContact1->setFlags ( CntWeakTerminal ); + // if (autoTarget->getGCell() == doglegGCell) + // dlContact1->migrateConstraintBox( autoTarget ); + // } else if (isTargetTerminal()) { + // unsetFlags( SegTargetTerminal ); + // setFlags( SegWeakTerminal1 ); + // segment1->setFlags( SegWeakTerminal1 ); + // segment2->setFlags( SegTargetTerminal ); + // autoSource->unsetFlags( CntWeakTerminal ); + // dlContact2->setFlags ( CntWeakTerminal ); + // if (autoSource->getGCell() == doglegGCell) + // dlContact2->migrateConstraintBox( autoSource ); + // } else if (isWeakTerminal()) { + // segment1->setFlags( SegWeakTerminal1 ); + // segment2->setFlags( SegWeakTerminal1 ); + // } + if (isAnalog()) { segment1->setFlags( SegAnalog ); segment2->setFlags( SegAnalog ); @@ -781,8 +816,11 @@ namespace Anabatic { updateNativeConstraints(); segment2->updateNativeConstraints(); + if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntHDogleg ); + if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntHDogleg ); + if (autoTarget->canDrag() and not autoSource->canDrag()) { - if (not autoTarget->getGCell()->isDevice()) { + if (not autoTarget->getGCell()->isDevice() and (segment1->getGCell() == autoTarget->getGCell())) { Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical); segment1->mergeUserConstraints( dragConstraints ); diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 19dd5a0e..7cb5b865 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -478,8 +478,8 @@ namespace Anabatic { maxPos = bb.getXMax(); cdebug_log(112,0) << "Vertical gauge: " << gauge << endl; - cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(ab.getXMin()) << endl; - cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(ab.getXMax()) << endl; + cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(bb.getXMin()) << endl; + cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(bb.getXMax()) << endl; cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl; } else { trackPos = gauge->getTrackPosition( ab.getYMin() @@ -490,8 +490,8 @@ namespace Anabatic { maxPos = bb.getYMax(); cdebug_log(112,0) << "Horizontal gauge: " << gauge << endl; - cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(ab.getYMin()) << endl; - cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(ab.getYMax()) << endl; + cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(bb.getYMin()) << endl; + cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(bb.getYMax()) << endl; cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getY()) << endl; } @@ -501,7 +501,7 @@ namespace Anabatic { cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl; if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { - if (not bestComponent or (bestSpan > maxPos-minPos)) { + if (not bestComponent or (bestSpan < maxPos-minPos)) { bestComponent = component; bestSpan = maxPos - minPos; } diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index f4c7147b..b7fa1784 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -43,6 +43,7 @@ namespace Anabatic { const BaseFlags Flags::ChannelRow = (1L << 13); const BaseFlags Flags::HRailGCell = (1L << 14); const BaseFlags Flags::VRailGCell = (1L << 15); + const BaseFlags Flags::GoStraight = (1L << 16); // Flags for Edge objects states only. const BaseFlags Flags::NullCapacity = (1L << 5); const BaseFlags Flags::InfiniteCapacity = (1L << 6); @@ -116,6 +117,7 @@ namespace Anabatic { const BaseFlags Flags::CheckLowUpDensity = (1L << 31); const BaseFlags Flags::NoUpdate = (1L << 32); const BaseFlags Flags::NorthPath = (1L << 33); + const BaseFlags Flags::UseNonPref = (1L << 34); Flags::~Flags () @@ -169,6 +171,7 @@ namespace Anabatic { return s.str(); } + string Flags::_getTypeName () const { return "Anabatic::Flags"; } diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 207af8d8..2cfe0373 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -1535,6 +1535,7 @@ namespace Anabatic { ++_connectedsId; for ( Vertex* vertex : connecteds ) { + vertex->getGCell()->flags().reset( Flags::GoStraight ); vertex->setDistance ( Vertex::unreached ); vertex->setStamp ( _stamp ); vertex->setConnexId ( _connectedsId ); diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 25a036e6..01acc0f9 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -1215,7 +1215,7 @@ namespace Anabatic { int GCell::getCapacity ( size_t depth ) const { const vector* edges = NULL; - if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_westEdges; + if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_eastEdges; else edges = (_northEdges.empty()) ? &_southEdges : &_northEdges; int capacity = 0; diff --git a/anabatic/src/LayerAssign.cpp b/anabatic/src/LayerAssign.cpp index 2b616f40..76ca3255 100644 --- a/anabatic/src/LayerAssign.cpp +++ b/anabatic/src/LayerAssign.cpp @@ -31,11 +31,287 @@ #include "hurricane/Horizontal.h" #include "hurricane/Cell.h" #include "crlcore/RoutingGauge.h" -#include "anabatic/AutoContact.h" +#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoSegment.h" #include "anabatic/AnabaticEngine.h" +namespace { + + + using namespace std; + using namespace CRL; + using namespace Hurricane; + using namespace Anabatic; + + + class SortRpByX { + public: + inline SortRpByX (); + inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 ); + }; + + + inline SortRpByX::SortRpByX () + { } + + + inline bool SortRpByX::operator() ( RoutingPad* rp1, RoutingPad* rp2 ) + { + DbU::Unit x1 = rp1->getCenter().getX(); + DbU::Unit x2 = rp2->getCenter().getX(); + + if (x1 == x2) return false; + return (x1 < x2); + } + + +// ----------------------------------------------------------------- +// Class : "RpsInRow". + + class RpsInRow { + public: + class Compare { + public: + bool operator() ( const RpsInRow* lhs, const RpsInRow* rhs ) const; + }; + public: + inline RpsInRow ( RoutingPad*, AnabaticEngine* ); + inline const vector& getRps () const; + inline size_t getSouth () const; + inline size_t getNorth () const; + inline const Interval& getRpsHSpan () const; + inline const Interval& getRpsVSpan () const; + void slacken (); + private: + void _findTopology (); + inline void _merge ( RoutingPad* ); + private: + AnabaticEngine* _anabatic; + vector _rps; + size_t _north; + size_t _south; + Interval _hSpan; + Interval _vSpan; + }; + + + inline RpsInRow::RpsInRow ( RoutingPad* seed, AnabaticEngine* anabatic ) + : _anabatic(anabatic) + , _rps () + , _north (0) + , _south (0) + , _hSpan () + , _vSpan ( false ) + { + _rps.push_back( seed ); + _findTopology(); + } + + + inline const vector& RpsInRow::getRps () const { return _rps; } + inline size_t RpsInRow::getSouth () const { return _south; } + inline size_t RpsInRow::getNorth () const { return _north; } + inline const Interval& RpsInRow::getRpsHSpan () const { return _hSpan; } + inline const Interval& RpsInRow::getRpsVSpan () const { return _vSpan; } + + + bool RpsInRow::Compare::operator() ( const RpsInRow* lhs, const RpsInRow* rhs ) const + { + if ( (lhs->_rps.size() == 2) and (rhs->_rps.size() != 2) ) return true; + if ( (lhs->_rps.size() != 2) and (rhs->_rps.size() == 2) ) return false; + if ( lhs->_rps.size() != rhs->_rps.size() ) return lhs->_rps.size() < rhs->_rps.size(); + + size_t lhsNs = lhs->_south + lhs->_north; + size_t rhsNs = rhs->_south + rhs->_north; + if (lhsNs != rhsNs) return lhsNs < rhsNs; + + if (lhs->_vSpan != rhs->_vSpan) return lhs->_vSpan.getSize() < rhs->_vSpan.getSize(); + if (lhs->_hSpan != rhs->_hSpan) return lhs->_hSpan.getSize() < rhs->_hSpan.getSize(); + + return lhs->_rps[0]->getId() < rhs->_rps[0]->getId(); + } + + + inline void RpsInRow::_merge ( RoutingPad* rp ) + { + if (rp != _rps[0]) _rps.push_back( rp ); + + Box bb ( _rps.back()->getBoundingBox() ); + _hSpan.merge( bb.getCenter().getX() ); + _vSpan.intersection( bb.getYMin(), bb.getYMax() ); + } + + + void RpsInRow::_findTopology () + { + cdebug_log(146,1) << "RpsInRow::findTopology() - " << _rps[0] << endl; + + _merge( _rps[0] ); + + AutoSegmentStack stack; + + for ( Component* component : _rps[0]->getSlaveComponents() ) { + cdebug_log(146,0) << "slave component: " << component << endl; + AutoContact* rpContact = Session::lookup( dynamic_cast(component) ); + if (rpContact) { + cdebug_log(146,0) << "Start rp: " << rpContact << endl; + + for ( AutoSegment* segment : rpContact->getAutoSegments() ) { + cdebug_log(146,0) << "Examining: " << segment << endl; + AutoContact* target = segment->getOppositeAnchor(rpContact); + + if (target) { + if (segment->isHorizontal()) { + stack.push( target, segment ); + } else { + if (segment->isLocal()) { + stack.push( target, segment ); + } else { + if (segment->getAutoSource() == rpContact) ++_north; + else ++_south; + } + } + } + } + + // Find Rps in same horizontal GCell range. + cdebug_log(146,0) << "Find Rps in same horizontal GCell range" << endl; + + while ( not stack.isEmpty() ) { + AutoSegment* from = stack.getAutoSegment(); + AutoContact* contact = stack.getAutoContact(); + stack.pop(); + + for ( AutoSegment* segment : contact->getAutoSegments() ) { + if (segment == from) continue; + if (segment->isVertical() and not segment->isLocal()) { + if (segment->getAutoSource() == contact) ++_north; + else ++_south; + continue; + } + + AutoContact* target = segment->getOppositeAnchor( contact ); + AutoContactTerminal* terminal = dynamic_cast( target ); + if (terminal) { + _merge( terminal->getRoutingPad() ); + } + + stack.push( target, segment ); + } + } + } + } + + sort( _rps.begin(), _rps.end(), SortRpByX() ); + + cdebug_log(146,0) << "findHAlignedsRps() - Exit" << endl; + cdebug_tabw(146,-1); + } + + + void RpsInRow::slacken () + { + cdebug_log(149,1) << "RpsInRow::slacken()" << endl; + + for ( RoutingPad* rp : _rps ) { + cdebug_log(149,0) << "Slacken from: " << rp << endl; + + if (rp->getLayer()) { + if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1) + cdebug_log(149,0) << "In METAL2, skiping" << endl; + continue; + } + + for ( Component* component : rp->getSlaveComponents() ) { + AutoContact* rpContact = Session::lookup( dynamic_cast(component) ); + if (rpContact) { + cdebug_log(149,0) << "+ " << rpContact << endl; + for ( AutoSegment* segment : rpContact->getAutoSegments() ) { + cdebug_log(149,0) << "| " << segment << endl; + + if (segment->isVertical()) { + if (segment->getDepth() == 1) { + cdebug_log(149,0) << "| Slacken: " << segment << endl; + segment->changeDepth( 2, Flags::NoFlags ); + cdebug_log(149,0) << "| After Slacken: " << segment << endl; + } + } else { + segment->makeDogleg( rpContact->getGCell() ); + cdebug_log(149,0) << "| Make dogleg: " << segment << endl; + } + } + } + } + } + cdebug_tabw(149,-1); + } + + +// ----------------------------------------------------------------- +// Class : "GCellRps". + + class GCellRps { + public: + class Compare { + public: + bool operator() ( const GCellRps* lhs, const GCellRps* rhs ) const; + }; + public: + GCellRps ( GCell*, AnabaticEngine* ); + ~GCellRps (); + inline GCell* getGCell () const; + inline size_t add ( RoutingPad* ); + inline void consolidate (); + inline RpsInRow* getRpsInRow ( size_t i ); + inline const vector& getRpsInRows () const; + private: + AnabaticEngine* _anabatic; + GCell* _gcell; + vector _rpsInRows; + }; + + + GCellRps::GCellRps ( GCell* gcell, AnabaticEngine* anabatic ) + : _anabatic (anabatic) + , _gcell (gcell) + , _rpsInRows() + { } + + + GCellRps::~GCellRps () + { + for ( RpsInRow* elem : _rpsInRows ) delete elem; + } + + + inline GCell* GCellRps::getGCell () const { return _gcell; } + + + inline size_t GCellRps::add ( RoutingPad* rp ) + { + _rpsInRows.push_back( new RpsInRow(rp,_anabatic) ); + return _rpsInRows.size() - 1; + } + + + inline void GCellRps::consolidate () + { + sort( _rpsInRows.begin(), _rpsInRows.end(), RpsInRow::Compare() ); + } + + + inline RpsInRow* GCellRps::getRpsInRow ( size_t i ) { return _rpsInRows[i]; } + inline const vector& GCellRps::getRpsInRows () const { return _rpsInRows; } + + + bool GCellRps::Compare::operator() ( const GCellRps* lhs, const GCellRps* rhs ) const + { return lhs->getGCell()->getId() < rhs->getGCell()->getId(); } + + +} // Anonymous namespace. + + namespace Anabatic { using Hurricane::DebugSession; @@ -645,6 +921,54 @@ namespace Anabatic { Session::setAnabaticFlags( Flags::WarnOnGCellOverload ); } + + set gcellRpss; + + for ( GCell* gcell : getGCells() ) { + set rps; + + const vector contacts = gcell->getContacts(); + for ( AutoContact* contact : contacts ) { + AutoContactTerminal* terminal = dynamic_cast( contact ); + if (terminal) { + rps.insert( terminal->getRoutingPad() ); + } + } + if (rps.size() > 8) { + GCellRps* gcellRps = new GCellRps ( gcell, this ); + gcellRpss.insert( gcellRps ); + + for ( RoutingPad* rp : rps ) gcellRps->add( rp ); + } + } + + for ( GCellRps* gcellRps : gcellRpss ) { + gcellRps->consolidate(); + + const vector& rpsInRows = gcellRps->getRpsInRows(); + cdebug_log(149,0) << gcellRps->getGCell() << " has " << rpsInRows.size() << " terminals." << endl; + + size_t count = 0; + for ( RpsInRow* rpsInRow : rpsInRows ) { + cdebug_log(149,0) << "North:" << rpsInRow->getNorth() << " South:" + << rpsInRow->getSouth() << " net:" + << rpsInRow->getRps()[0]->getNet()->getName() << endl; + cdebug_log(149,0) << "H-Span:" << rpsInRow->getRpsHSpan() << " V-Span:" << rpsInRow->getRpsVSpan() << endl; + for ( RoutingPad* arp : rpsInRow->getRps() ) { + cdebug_log(149,0) << "| " << arp << endl; + } + if (++count < 2) rpsInRow->slacken(); + } + + for ( AutoSegment* segment : gcellRps->getGCell()->getHSegments() ) { + if (segment->canPivotUp()) { + cdebug_log(149,0) << "Move up horizontal: " << segment << endl; + segment->moveUp( Flags::Propagate ); + } + } + + delete gcellRps; + } checkGCellDensities(); Session::close(); diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index 5e55bb4e..eec4f6d7 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -165,27 +165,81 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; + size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); AutoContact* rpSourceContact; AutoContact* rpContactTarget; + Flags useNonPref = Flags::NoFlags; + if (flags & UseNonPref) useNonPref |= Flags::UseNonPref; + flags |= checkRoutingPadSize( rp ); doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, flags ); - if (flags & HAccess) { - if (flags & VSmall) { - AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); - AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); - AutoSegment::create( subContact1, subContact2, Flags::Vertical ); - rpSourceContact = subContact2; + cdebug_log(145,0) << "flags: " << flags << endl; + if ((rpDepth == 0) or (rpDepth == 2)) { + cdebug_log(145,0) << "case: METAL1 or METAL3 RoutingPad." << endl; + + if (flags & HAccess) { + cdebug_log(145,0) << "case: HAccess" << endl; + + if ( ((flags & VSmall) and not ((flags & UseNonPref)) or (flags & Punctual)) ) { + cdebug_log(145,0) << "case: VSmall and *not* UseNonPref" << endl; + + AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); + rpSourceContact = subContact1; + + flags &= ~UseNonPref; + useNonPref.reset( Flags::UseNonPref ); + } + + if (flags & (VSmall|UseNonPref)) { + cdebug_log(145,0) << "case: UseNonPref" << endl; + + AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|useNonPref ); + rpSourceContact = subContact1; + } + } else { + if (flags & HSmall) { + cdebug_log(145,0) << "case: HSmall" << endl; + + AutoContact* subContact1 = rpSourceContact; + AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( subContact1, subContact2, Flags::Horizontal ); + rpSourceContact = subContact2; + + if (flags & Punctual) { + cdebug_log(145,0) << "case: HSmall + Punctual" << endl; + subContact1 = subContact2; + subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( subContact1, subContact2, Flags::Vertical ); + + subContact1 = subContact2; + subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + AutoSegment::create( subContact1, subContact2, Flags::Horizontal ); + + rpSourceContact = subContact2; + } + } } } else { - if (flags & HSmall) { - AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + cdebug_log(145,0) << "case: METAL2." << endl; + AutoContact* subContact1 = NULL; + + if (flags & HAccess) { + if (flags & HAccessEW) + subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + else + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); + + AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical ); + } else { + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); - rpSourceContact = subContact1; } + rpSourceContact = subContact1; } cdebug_tabw(145,-1); @@ -198,6 +252,7 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl; +#if THIS_IS_DISABLED uint64_t flags = NoFlags; if (east() ) { flags |= HAccess; } else if (west() ) { flags |= HAccess; } @@ -205,8 +260,16 @@ namespace Anabatic { else if (south()) { flags |= VSmall; } setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],flags) ); +#endif + + if (north() or south()) { + setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],VSmall) ); + } else { + setBothCornerContacts( doRp_Access( getGCell(), getRoutingPads()[0], UseNonPref|HAccess ) ); + } cdebug_tabw(145,-1); + return true; } @@ -217,8 +280,8 @@ namespace Anabatic { sortRpByX( getRoutingPads(), NoFlags ); // increasing X. for ( size_t i=1 ; igetBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; - if (getRoutingPads()[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) { - cdebug_log(145,0) << "| Better RP: " << southWestRp << endl; - southWestRp = getRoutingPads()[i]; - } - } + // for ( size_t i=1 ; igetBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; + // if (getRoutingPads()[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) { + // southWestRp = getRoutingPads()[i]; + // cdebug_log(145,0) << "| Better RP: " << southWestRp << endl; + // } + // } if (west() and not south()) { setSouthWestContact( doRp_Access( getGCell(), southWestRp, HAccess ) ); @@ -883,11 +987,17 @@ namespace Anabatic { biggestRp = getRoutingPads()[i]; } - const Layer* viaLayer1 = Session::getContactLayer(1); - AutoContact* unusedContact = NULL; + const Layer* viaLayer1 = Session::getContactLayer(1); + + if (east() and west() and not south() and not north()) { + AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, HBothAccess ); + setBothCornerContacts( rpContact ); + cdebug_tabw(145,-1); + return true; + } if (west() and not south()) { - doRp_AutoContacts( getGCell(), getRoutingPads()[0], getSouthWestContact(), unusedContact, DoSourceContact ); + setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) ); } else if (not west() and south()) { setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) ); } else if (west() and south()) { @@ -897,7 +1007,7 @@ namespace Anabatic { } if (east() and not north()) { - doRp_AutoContacts( getGCell(), getRoutingPads()[getRoutingPads().size()-1], getNorthEastContact(), unusedContact, DoSourceContact ); + setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) ); } else if (not east() and north()) { setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) ); } else if (east() and north()) { diff --git a/anabatic/src/NetConstraints.cpp b/anabatic/src/NetConstraints.cpp index 0e500090..97a31c2e 100644 --- a/anabatic/src/NetConstraints.cpp +++ b/anabatic/src/NetConstraints.cpp @@ -61,55 +61,55 @@ namespace { void propagateConstraintFromRp ( RoutingPad* rp ) { - cdebug_log(145,1) << "propagateConstraintFromRp() - " << rp << endl; + cdebug_log(146,1) << "propagateConstraintFromRp() - " << rp << endl; for ( Component* component : rp->getSlaveComponents() ) { - cdebug_log(145,0) << "slave component: " << component << endl; + cdebug_log(146,0) << "slave component: " << component << endl; AutoContact* sourceContact = Session::lookup( dynamic_cast(component) ); if (sourceContact) { Box constraintBox = sourceContact->getConstraintBox(); - cdebug_log(145,0) << "Start slave: " << sourceContact << endl; - cdebug_log(145,0) << "Constraint: " << constraintBox << endl; + cdebug_log(146,0) << "Start slave: " << sourceContact << endl; + cdebug_log(146,0) << "Constraint: " << constraintBox << endl; set verticalSegments; set horizontalSegments; for ( AutoSegment* segment : sourceContact->getAutoSegments() ) { - cdebug_log(145,0) << "Examining: " << segment << endl; + cdebug_log(146,0) << "Examining: " << segment << endl; AutoContact* targetContact = segment->getOppositeAnchor(sourceContact); if (targetContact) { if (segment->isHorizontal()) { - cdebug_log(145,0) << "On horizontal stack " << segment << endl; + cdebug_log(146,0) << "On horizontal stack " << segment << endl; horizontalSegments.insert( segment ); } else { - cdebug_log(145,0) << "On vertical stack " << segment << endl; + cdebug_log(146,0) << "On vertical stack " << segment << endl; verticalSegments.insert( segment ); } } } // Propagate constraint through horizontally aligned segments. - cdebug_log(145,0) << "Propagate constraint on horizontal segments" << endl; + cdebug_log(146,0) << "Propagate constraint on horizontal segments" << endl; for ( AutoSegment* horizontal : horizontalSegments ) { AutoContact* contact = NULL; for ( AutoSegment* aligned : horizontal->getAligneds(Flags::WithSelf) ) { - cdebug_log(145,0) << "aligned horizontal: " << aligned << endl; + cdebug_log(146,0) << "aligned horizontal: " << aligned << endl; contact = aligned->getAutoTarget(); - cdebug_log(145,0) << "contact: " << contact << endl; + cdebug_log(146,0) << "contact: " << contact << endl; if (contact) { - cdebug_log(145,0) << "Apply to (target): " << contact << endl; + cdebug_log(146,0) << "Apply to (target): " << contact << endl; contact->restrictConstraintBox( constraintBox.getYMin() , constraintBox.getYMax() , Flags::Horizontal|Flags::WarnOnError ); } contact = aligned->getAutoSource(); - cdebug_log(145,0) << "contact: " << contact << endl; + cdebug_log(146,0) << "contact: " << contact << endl; if (contact) { - cdebug_log(145,0) << "Apply to (source): " << contact << endl; + cdebug_log(146,0) << "Apply to (source): " << contact << endl; contact->restrictConstraintBox( constraintBox.getYMin() , constraintBox.getYMax() , Flags::Horizontal|Flags::WarnOnError ); @@ -118,23 +118,23 @@ namespace { } // Propagate constraint through vertically aligned segments. - cdebug_log(145,0) << "Propagate constraint on vertical segments" << endl; + cdebug_log(146,0) << "Propagate constraint on vertical segments" << endl; for ( AutoSegment* vertical : verticalSegments ) { AutoContact* contact = NULL; for ( AutoSegment* aligned : vertical->getAligneds(Flags::WithSelf) ) { - cdebug_log(145,0) << "aligned vertical: " << aligned << endl; + cdebug_log(146,0) << "aligned vertical: " << aligned << endl; contact = aligned->getAutoTarget(); if (contact) { - cdebug_log(145,0) << "Apply to (target): " << contact << endl; + cdebug_log(146,0) << "Apply to (target): " << contact << endl; contact->restrictConstraintBox( constraintBox.getXMin() , constraintBox.getXMax() , Flags::Vertical|Flags::WarnOnError ); } contact = aligned->getAutoSource(); if (contact) { - cdebug_log(145,0) << "Apply to (source): " << contact << endl; + cdebug_log(146,0) << "Apply to (source): " << contact << endl; contact->restrictConstraintBox( constraintBox.getXMin() , constraintBox.getXMax() , Flags::Vertical|Flags::WarnOnError ); @@ -144,8 +144,8 @@ namespace { } } - cdebug_log(145,0) << "propagateConstraintFromRp() - Exit" << endl; - cdebug_tabw(145,-1); + cdebug_log(146,0) << "propagateConstraintFromRp() - Exit" << endl; + cdebug_tabw(146,-1); } @@ -159,12 +159,78 @@ namespace Anabatic { using Hurricane::Cell; + void propagateDistanceFromRp ( RoutingPad* rp ) + { + cdebug_log(146,1) << "propagateDistanceFromRp() - " << rp << endl; + + unsigned int distance = 0; + vector< pair > currents; + vector< pair > successors; + + for ( Component* component : rp->getSlaveComponents() ) { + cdebug_log(146,0) << "slave component: " << component << endl; + + AutoContact* sourceContact = Session::lookup( dynamic_cast(component) ); + if (sourceContact) { + cdebug_log(146,0) << "Start slave: " << sourceContact << endl; + + for ( AutoSegment* segment : sourceContact->getAutoSegments() ) { + cdebug_log(146,0) << "Pushing: " << segment << endl; + currents.push_back( make_pair(sourceContact,segment) ); + } + } + } + + while ( not currents.empty() ) { + for ( size_t i = 0 ; igetRpDistance() == 1) ) { + vector gcells; + segment->getGCells( gcells ); + + if (gcells.size() < 3) + segment->setFlags( AutoSegment::SegUnbreakable ); + } + + if (distance >= segment->getRpDistance()) continue; + segment->setRpDistance( distance ); + cdebug_log(146,0) << "Popped: " << segment << endl; + + AutoContact* target = segment->getOppositeAnchor( source ); + if (target) { + for ( AutoSegment* successor : target->getAutoSegments() ) { + if (successor == segment) continue; + + // if (successor->isNonPref()) { + // cdebug_log(146,0) << "Pushing (non-pref): " << successor << endl; + // currents.push_back( make_pair(target,successor) ); + // } else { + cdebug_log(146,0) << "Pushing: " << successor << endl; + successors.push_back( make_pair(target,successor) ); + // } + } + } + } + + if (++distance > 15) break; + + currents.clear(); + currents.swap( successors ); + } + + cdebug_log(146,0) << "propagateDistanceFromRp() - Exit" << endl; + cdebug_tabw(146,-1); + } + + void AnabaticEngine::computeNetConstraints ( Net* net ) { - DebugSession::open( net, 145, 150); + DebugSession::open( net, 146, 150); cdebug_log(149,0) << "Anabatic::computeNetConstraints( " << net << " )" << endl; - cdebug_tabw(145,1); + cdebug_tabw(146,1); vector routingPads; forEach ( Component*, icomponent, net->getComponents() ) { @@ -179,15 +245,35 @@ namespace Anabatic { } } - for ( size_t i=0 ; igetSegments() ) { + AutoSegment* autoSegment = Session::lookup( segment ); + if (not autoSegment) continue; + if (autoSegment->isUnbreakable()) continue; + if (autoSegment->getRpDistance() >= 2) continue; + if (autoSegment->getRpDistance() == 1) continue; + + vector gcells; + autoSegment->getGCells( gcells ); + + if (gcells.size() > 2) continue; + //if ( (gcells.size() == 2) + // and ( not autoSegment->getAutoSource()->isTerminal() + // or not autoSegment->getAutoTarget()->isTerminal()) ) continue; + + autoSegment->setFlags( AutoSegment::SegUnbreakable ); + } // forEach ( Segment*, isegment, net->getSegments() ) { // AutoSegment* autoSegment = Session::lookup( *isegment ); // if (autoSegment) autoSegment->toConstraintAxis(); // } - cdebug_tabw(145,-1); + cdebug_tabw(146,-1); DebugSession::close(); } diff --git a/anabatic/src/Session.cpp b/anabatic/src/Session.cpp index c4dae6ff..074f51ad 100644 --- a/anabatic/src/Session.cpp +++ b/anabatic/src/Session.cpp @@ -215,7 +215,7 @@ namespace Anabatic { _anabatic->updateNetTopology ( net ); _anabatic->computeNetConstraints( net ); _anabatic->_computeNetOptimals ( net ); - _anabatic->_computeNetTerminals ( net ); + //_anabatic->_computeNetTerminals ( net ); } _canonize (); diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index cbda82ae..d09d1ba7 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -161,7 +161,12 @@ namespace Anabatic { inline bool operator() ( const NetData* lhs, const NetData* rhs ) const { if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute(); - if (lhs->getSparsity() != rhs->getSparsity() ) return lhs->getSparsity() < rhs->getSparsity(); + if ((lhs->getRpCount() > 10) or (rhs->getRpCount() > 10)) { + if (lhs->getRpCount() != rhs->getRpCount()) + return lhs->getRpCount() > rhs->getRpCount(); + } + + if (lhs->getSparsity() != rhs->getSparsity()) return lhs->getSparsity() < rhs->getSparsity(); return lhs->getNet()->getId() < rhs->getNet()->getId(); } }; diff --git a/anabatic/src/anabatic/AutoContact.h b/anabatic/src/anabatic/AutoContact.h index e2de5a63..6c85299d 100644 --- a/anabatic/src/anabatic/AutoContact.h +++ b/anabatic/src/anabatic/AutoContact.h @@ -71,6 +71,8 @@ namespace Anabatic { , CntOnVertical = (1 << 14) , CntOnHorizontal = (1 << 15) , CntDrag = (1 << 16) + , CntHDogleg = (1 << 17) + , CntVDogleg = (1 << 18) }; class AutoContact { @@ -119,6 +121,8 @@ namespace Anabatic { inline bool isVTee () const; inline bool isFixed () const; inline bool isUserNativeConstraints () const; + inline bool isHDogleg () const; + inline bool isVDogleg () const; inline bool hasBadTopology () const; bool canDestroy ( Flags flags=Flags::NoFlags ) const; bool canMoveUp ( const AutoSegment* moved ) const; @@ -259,6 +263,8 @@ namespace Anabatic { inline bool AutoContact::isTerminal () const { return _flags&CntTerminal; } inline bool AutoContact::isHTee () const { return _flags&CntHTee; } inline bool AutoContact::isVTee () const { return _flags&CntVTee; } + inline bool AutoContact::isHDogleg () const { return _flags&CntHDogleg; } + inline bool AutoContact::isVDogleg () const { return _flags&CntVDogleg; } inline bool AutoContact::hasBadTopology () const { return _flags&CntBadTopology; } inline bool AutoContact::canDrag () const { return _flags&CntDrag; } inline size_t AutoContact::getId () const { return _id; } diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index b98ec0e4..89ee9fdc 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -58,11 +58,10 @@ namespace Anabatic { class AutoHorizontal; class AutoVertical; + // ------------------------------------------------------------------- // Class : "AutoSegment". - - class AutoSegment { friend class AutoHorizontal; friend class AutoVertical; @@ -106,6 +105,8 @@ namespace Anabatic { static const uint64_t SegAnalog = (1L<<33); static const uint64_t SegWide = (1L<<34); static const uint64_t SegShortNet = (1L<<35); + static const uint64_t SegUnbreakable = (1L<<36); + static const uint64_t SegNonPref = (1L<<37); // Masks. static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; @@ -194,6 +195,8 @@ namespace Anabatic { inline bool isWeakTerminal1 () const; inline bool isWeakTerminal2 () const; inline bool isTerminal () const; + inline bool isUnbreakable () const; + inline bool isNonPref () const; inline bool isDrag () const; inline bool isNotSourceAligned () const; inline bool isNotTargetAligned () const; @@ -245,6 +248,7 @@ namespace Anabatic { AutoContact* getOppositeAnchor ( AutoContact* ) const; size_t getPerpandicularsBound ( set& ); inline AutoSegment* getParent () const; + inline unsigned int getRpDistance () const; inline unsigned int getDepth () const; inline DbU::Unit getPitch () const; DbU::Unit getPPitch () const; @@ -282,6 +286,7 @@ namespace Anabatic { inline void unsetFlags ( uint64_t ); inline void setFlags ( uint64_t ); void setFlagsOnAligneds ( uint64_t ); + inline void setRpDistance ( unsigned int ); inline void incReduceds (); inline void decReduceds (); virtual void setDuSource ( DbU::Unit du ) = 0; @@ -370,10 +375,11 @@ namespace Anabatic { const unsigned long _id; GCell* _gcell; uint64_t _flags; - unsigned int _depth : 8; - unsigned int _optimalMin :16; - unsigned int _optimalMax :16; - unsigned int _reduceds : 2; + unsigned int _depth : 8; + unsigned int _optimalMin :16; + unsigned int _optimalMax :16; + unsigned int _reduceds : 2; + unsigned int _rpDistance : 4; DbU::Unit _sourcePosition; DbU::Unit _targetPosition; Interval _userConstraints; @@ -484,6 +490,7 @@ namespace Anabatic { inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); } inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); } inline unsigned int AutoSegment::getDepth () const { return _depth; } + inline unsigned int AutoSegment::getRpDistance () const { return _rpDistance; } inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); } inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); } inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); } @@ -503,13 +510,15 @@ namespace Anabatic { inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; } inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; } inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); } + inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; } + inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; } inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; } - inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; } - inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; } - inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; } + inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); } + inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); } + inline bool AutoSegment::isWeakTerminal2 () const { return (_rpDistance == 2); } inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; } inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; } - inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; } + inline bool AutoSegment::isTerminal () const { return (_rpDistance == 0); } inline bool AutoSegment::isDrag () const { return _flags & SegDrag; } inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; } inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; } @@ -537,6 +546,7 @@ namespace Anabatic { inline uint64_t AutoSegment::getFlags () const { return _flags; } inline uint64_t AutoSegment::_getFlags () const { return _flags; } + inline void AutoSegment::setRpDistance ( unsigned int distance ) { _rpDistance=distance; } inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; } inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; } inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; } diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 4ff880b9..46a124f9 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -43,6 +43,7 @@ namespace Anabatic { static const BaseFlags ChannelRow ; // = (1 << 13); static const BaseFlags HRailGCell ; // = (1 << 14); static const BaseFlags VRailGCell ; // = (1 << 15); + static const BaseFlags GoStraight ; // = (1 << 16); // Flags for Edge objects states only. static const BaseFlags NullCapacity ; // = (1 << 5); static const BaseFlags InfiniteCapacity ; // = (1 << 6); @@ -99,6 +100,7 @@ namespace Anabatic { static const BaseFlags CheckLowUpDensity ; static const BaseFlags NoUpdate ; static const BaseFlags NorthPath ; + static const BaseFlags UseNonPref ; public: inline Flags ( uint64_t flags = NoFlags ); inline Flags ( const Hurricane::BaseFlags& ); diff --git a/anabatic/src/anabatic/Edge.h b/anabatic/src/anabatic/Edge.h index 8e92f42b..20f25ddd 100644 --- a/anabatic/src/anabatic/Edge.h +++ b/anabatic/src/anabatic/Edge.h @@ -136,7 +136,6 @@ namespace Anabatic { inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); } - inline unsigned int Edge::getCapacity () const { return (_capacities) ? _capacities->getCapacity()-_reservedCapacity : 0; } inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; } inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; } inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; } @@ -156,6 +155,12 @@ namespace Anabatic { inline Flags& Edge::flags () { return _flags; } inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; } inline void Edge::reserveCapacity ( int delta ) { _reservedCapacity = ((int)_reservedCapacity+delta > 0) ? _reservedCapacity+delta : 0; } + + inline unsigned int Edge::getCapacity () const + { + if (not _capacities) return 0; + return (_capacities->getCapacity() > (int)_reservedCapacity) ? _capacities->getCapacity()-_reservedCapacity : 0; + } } // Anabatic namespace. diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index d4d8712b..e47c994d 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -147,6 +147,7 @@ namespace Anabatic { inline bool isMatrix () const; inline bool isRow () const; inline bool isIoPad () const; + inline bool isGoStraight () const; inline bool isHRail () const; inline bool isVRail () const; inline bool isStdCellRow () const; @@ -341,6 +342,7 @@ namespace Anabatic { inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; } inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; } inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; } + inline bool GCell::isGoStraight () const { return _flags & Flags::GoStraight; } inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; } inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; } inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; } diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index 8cf01331..db4ed055 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -98,6 +98,8 @@ namespace Anabatic { , WestBound = (1 << 14) , EastBound = (1 << 15) , Middle = (1 << 16) + , UseNonPref = (1 << 17) + , HBothAccess = HAccess|HAccessEW , SouthWest = SouthBound|WestBound , NorthEast = NorthBound|EastBound }; diff --git a/crlcore/etc/common/technology.conf b/crlcore/etc/common/technology.conf index 7c62d042..1a35cc68 100644 --- a/crlcore/etc/common/technology.conf +++ b/crlcore/etc/common/technology.conf @@ -241,6 +241,7 @@ symbolicLayersExtensionsTable = \ , ('METAL3.metal3.extention.cap' , l( 1.0)) , ('METAL4.minimum.width' , l( 1.0)) , ('METAL4.metal4.extention.cap' , l( 1.0)) + , ('METAL4.minimalSpacing' , l( 3.0)) , ('METAL5.minimum.width' , l( 2.0)) , ('METAL5.metal5.extention.cap' , l( 1.0)) , ('METAL6.minimum.width' , l( 2.0)) diff --git a/crlcore/etc/symbolic/cmos/kite.conf b/crlcore/etc/symbolic/cmos/kite.conf index b020336e..4251d91c 100644 --- a/crlcore/etc/symbolic/cmos/kite.conf +++ b/crlcore/etc/symbolic/cmos/kite.conf @@ -9,6 +9,7 @@ execfile( helpers.sysConfDir+'/common/kite.conf' ) parametersTable = \ ( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 ) + , ('katabatic.routingGauge' ,TypeString , 'sxlib' ) , ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters. , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) diff --git a/crlcore/src/ccore/Histogram.cpp b/crlcore/src/ccore/Histogram.cpp index d094033d..6019d3ae 100644 --- a/crlcore/src/ccore/Histogram.cpp +++ b/crlcore/src/ccore/Histogram.cpp @@ -1,15 +1,14 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) Sorbonne Universite 2008-2019, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | // | Alliance / Hurricane Interface | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./Histogram.cpp" | // +-----------------------------------------------------------------+ @@ -31,6 +30,7 @@ namespace CRL { using std::ofstream; using std::ostringstream; using std::setprecision; + using std::setw; using std::vector; using Hurricane::Record; @@ -41,13 +41,16 @@ namespace CRL { , _mainTitle () , _titles (nbSets) , _colors (nbSets) + , _indents (nbSets) , _sets (nbSets) , _totalSamples (nbSets) , _fileExtension() { - size_t binSize = (size_t)rint ( _range / _step ); - for ( size_t iset=0 ; iset(binSize); + if (_range != 0.0) { + size_t binSize = (size_t)rint( _range / _step ); + for ( size_t iset=0 ; iset( binSize ); + } } } @@ -58,10 +61,16 @@ namespace CRL { void Histogram::addSample ( double sample, size_t iset ) { - if ( iset >= _sets.size() ) return; + if (iset >= _sets.size()) return; - size_t binIndex = (size_t)rint ( sample / _step ); - if ( binIndex >= _sets.front().size() ) binIndex = _sets.front().size() - 1; + size_t binIndex = (size_t)rint( sample / _step ); + if (_range != 0.0) { + if (binIndex >= _sets.front().size()) binIndex = _sets.front().size() - 1; + } else { + while ( _sets.front().size() < binIndex + 1) { + for ( vector& rset : _sets ) rset.push_back( 0.0 ); + } + } _sets [iset][binIndex] += 1.0; _totalSamples[iset]++; @@ -101,7 +110,38 @@ namespace CRL { } - void Histogram::toFile ( const string& path ) + string Histogram::toString ( size_t iset ) + { + if (iset >= _sets.size()) return ""; + + ostringstream s; + + size_t titleWidth = _titles[iset].size(); + + string hline = _indents[iset] + "+-" + string(titleWidth,'-') + "-+-------------+----+\n"; + string tline = _indents[iset] + "| " + _titles[iset] + " | Count | % |\n"; + + s << hline << tline << hline; + + for ( size_t i=0 ; i<_sets[iset].size() ; ++i ) { + float value = _sets[iset][i]; + if ((value == 0.0) and (_range == 0.0)) continue; + + size_t percent = value*100.0 / _totalSamples[iset]; + s << _indents[iset] + << "| " << setw(titleWidth) << (size_t)(_step*i) + << " | " << setw(11) << (size_t)(value) + << " | " << setw( 2) << percent + << " | " << string( percent, '*' ) + << "\n"; + } + + s << hline; + return s.str(); + } + + + void Histogram::toFile ( string path ) { ofstream fd ( path.c_str() ); toStream ( fd ); @@ -109,7 +149,7 @@ namespace CRL { } - void Histogram::toGnuplot ( const string& basename ) + void Histogram::toGnuplot ( string basename ) { Utilities::Path datFile ( basename+_fileExtension+".dat" ); toFile ( datFile.toString() ); diff --git a/crlcore/src/ccore/crlcore/Histogram.h b/crlcore/src/ccore/crlcore/Histogram.h index bf8e2183..dd273ce7 100644 --- a/crlcore/src/ccore/crlcore/Histogram.h +++ b/crlcore/src/ccore/crlcore/Histogram.h @@ -1,30 +1,21 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) Sorbonne Universite 2008-2019, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | Alliance / Hurricane Interface | // | | // | Author : Jean-Paul Chaput | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./Histogram.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./crlcore/Histogram.h" | +// +-----------------------------------------------------------------+ -#ifndef __CRL_HISTOGRAM__ -#define __CRL_HISTOGRAM__ +#ifndef CRL_HISTOGRAM_H +#define CRL_HISTOGRAM_H #include #include @@ -40,15 +31,17 @@ namespace CRL { public: Histogram ( double range, double step, size_t nbSets ); ~Histogram (); - inline void setMainTitle ( const std::string& ); - inline void setTitle ( const std::string&, size_t iset ); - inline void setColor ( const std::string&, size_t iset ); + inline void setMainTitle ( std::string ); + inline void setTitle ( std::string, size_t iset ); + inline void setColor ( std::string, size_t iset ); + inline void setIndent ( std::string, size_t iset ); void addSample ( double, size_t iset ); - inline void setFileExtension ( const std::string& ); + inline void setFileExtension ( std::string ); float getYRange () const; void toStream ( std::ostream& ); - void toFile ( const std::string& ); - void toGnuplot ( const std::string& basename ); + std::string toString ( size_t iset ); + void toFile ( std::string ); + void toGnuplot ( std::string basename ); void normalize ( size_t iset ); std::string _getString () const; Hurricane::Record* _getRecord () const; @@ -58,6 +51,7 @@ namespace CRL { std::string _mainTitle; std::vector< std::string > _titles; std::vector< std::string > _colors; + std::vector< std::string > _indents; std::vector< std::vector > _sets; std::vector< int > _totalSamples; std::string _fileExtension; @@ -65,10 +59,11 @@ namespace CRL { // Inline Functions. - inline void Histogram::setMainTitle ( const std::string& title ) { _mainTitle=title; } - inline void Histogram::setTitle ( const std::string& title, size_t iset ) { if (iset<_titles.size()) _titles[iset] = title; } - inline void Histogram::setColor ( const std::string& color, size_t iset ) { if (iset<_colors.size()) _colors[iset] = color; } - inline void Histogram::setFileExtension ( const std::string& extension ) { _fileExtension=extension; } + inline void Histogram::setMainTitle ( std::string title ) { _mainTitle=title; } + inline void Histogram::setTitle ( std::string title , size_t iset ) { if (iset<_titles .size()) _titles[iset ] = title; } + inline void Histogram::setColor ( std::string color , size_t iset ) { if (iset<_colors .size()) _colors[iset ] = color; } + inline void Histogram::setIndent ( std::string indent, size_t iset ) { if (iset<_indents.size()) _indents[iset] = indent; } + inline void Histogram::setFileExtension ( std::string extension ) { _fileExtension=extension; } template<> @@ -80,7 +75,7 @@ namespace CRL { inline Histogram* getData () const; inline void setData ( Histogram* ); virtual std::string toString () const; - virtual void toGnuplot ( const std::string& basename ) const; + virtual void toGnuplot ( std::string basename ) const; virtual std::string _getString () const; virtual Record* _getRecord () const; private: @@ -102,7 +97,7 @@ namespace CRL { std::string Measure::toString () const { return "Unsupported"; } - void Measure::toGnuplot ( const std::string& basename ) const + void Measure::toGnuplot ( std::string basename ) const { _data->toGnuplot ( basename ); } std::string Measure::_getString () const @@ -118,9 +113,9 @@ namespace CRL { } -} // End of CRL namespace. +} // CRL namespace. INSPECTOR_P_SUPPORT(CRL::Histogram) -#endif // __CRL_HISTOGRAM__ +#endif // CRL_HISTOGRAM_H diff --git a/cumulus/src/plugins/ClockTreePlugin.py b/cumulus/src/plugins/ClockTreePlugin.py index f8e9042c..78e7373a 100755 --- a/cumulus/src/plugins/ClockTreePlugin.py +++ b/cumulus/src/plugins/ClockTreePlugin.py @@ -97,7 +97,7 @@ def ScriptMain ( **kw ): conf = chip.Configuration.ChipConf( {}, cell, editor ) if cell.getAbutmentBox().isEmpty(): - spaceMargin = Cfg.getParamPercentage('etesian.spaceMargin').asPercentage() / 100.0 + 0.02 + spaceMargin = Cfg.getParamPercentage('etesian.spaceMargin').asPercentage() / 100.0 + 0.01 aspectRatio = Cfg.getParamPercentage('etesian.aspectRatio').asPercentage() / 100.0 clocktree.ClockTree.computeAbutmentBox( cell, spaceMargin, aspectRatio, conf.cellGauge ) if editor: editor.fit() diff --git a/cumulus/src/plugins/chip/BlockCorona.py b/cumulus/src/plugins/chip/BlockCorona.py index e83bb9fc..7e4f279d 100644 --- a/cumulus/src/plugins/chip/BlockCorona.py +++ b/cumulus/src/plugins/chip/BlockCorona.py @@ -29,6 +29,7 @@ from Hurricane import Net from Hurricane import Contact from Hurricane import Horizontal from Hurricane import Vertical +from Hurricane import Pad import CRL from CRL import RoutingLayerGauge from helpers import trace @@ -421,6 +422,20 @@ class VerticalSide ( Side ): , sideXMin , sideXMax ) + + depth -= 2 + if depth > 0: + blockageLayer = routingGauge.getRoutingLayer(depth).getBlockageLayer() + pitch = routingGauge.getLayerPitch(depth) + + for chunk in spans.chunks: + Horizontal.create( self.blockageNet + , blockageLayer + , (chunk.getVMax() + chunk.getVMin())/2 + , chunk.getVMax() - chunk.getVMin() + pitch*2 + , sideXMin + , sideXMax + ) return @@ -542,6 +557,11 @@ class Corona ( object ): contactDepth = self.verticalDepth UpdateSession.open() + blBox = Box() + brBox = Box() + tlBox = Box() + trBox = Box() + for i in range(self.railsNb): xBL = self.westSide .getRail(i).axis yBL = self.southSide.getRail(i).axis @@ -549,6 +569,11 @@ class Corona ( object ): yTR = self.northSide.getRail(i).axis net = self.getRailNet( i ) + blBox.merge( xBL, yBL ) + brBox.merge( xTR, yBL ) + tlBox.merge( xBL, yTR ) + trBox.merge( xTR, yTR ) + self.routingGauge.getContactLayer(contactDepth) self.corners[chip.SouthWest].append( Contact.create( net @@ -586,5 +611,19 @@ class Corona ( object ): self.westSide.addBlockages() self.eastSide.addBlockages() + + blBox.inflate( self.hRailWidth, self.vRailWidth ) + brBox.inflate( self.hRailWidth, self.vRailWidth ) + tlBox.inflate( self.hRailWidth, self.vRailWidth ) + trBox.inflate( self.hRailWidth, self.vRailWidth ) + + for depth in range( 1, self.conf.gaugeConf.topLayerDepth + 1 ): + blockageLayer = self.routingGauge.getRoutingLayer(depth).getBlockageLayer() + + Pad.create( self.blockageNet, blockageLayer, blBox ) + Pad.create( self.blockageNet, blockageLayer, brBox ) + Pad.create( self.blockageNet, blockageLayer, tlBox ) + Pad.create( self.blockageNet, blockageLayer, trBox ) + UpdateSession.close() return diff --git a/cumulus/src/plugins/clocktree/ClockTree.py b/cumulus/src/plugins/clocktree/ClockTree.py index d48ab17c..fff7fde2 100755 --- a/cumulus/src/plugins/clocktree/ClockTree.py +++ b/cumulus/src/plugins/clocktree/ClockTree.py @@ -42,6 +42,7 @@ try: import helpers from helpers import trace from helpers.io import ErrorMessage + import Etesian import Unicorn import plugins from clocktree.RSMT import RSMT @@ -585,36 +586,40 @@ class HTreeNode ( object ): def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ): - sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() ) - - instancesNb = 0 - cellLength = 0 - for occurrence in cell.getLeafInstanceOccurrences(): - instance = occurrence.getEntity() - instancesNb += 1 - cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) ) - - # ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2 - # y = sqrt(S/AR) - gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight - rows = math.sqrt( gcellLength/aspectRatio ) - if math.trunc(rows) != rows: rows = math.trunc(rows) + 1 - else: rows = math.trunc(rows) - columns = gcellLength / rows - if math.trunc(columns) != columns: columns = math.trunc(columns) + 1 - else: columns = math.trunc(columns) - - print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \ - % (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight)) - print ' - GCell grid: [%dx%d]' % (columns,rows) + # sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() ) + # + # instancesNb = 0 + # cellLength = 0 + # for occurrence in cell.getLeafInstanceOccurrences(): + # instance = occurrence.getEntity() + # instancesNb += 1 + # cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) ) + # + # # ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2 + # # y = sqrt(S/AR) + # gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight + # rows = math.sqrt( gcellLength/aspectRatio ) + # if math.trunc(rows) != rows: rows = math.trunc(rows) + 1 + # else: rows = math.trunc(rows) + # columns = gcellLength / rows + # if math.trunc(columns) != columns: columns = math.trunc(columns) + 1 + # else: columns = math.trunc(columns) + # + # print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \ + # % (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight)) + # print ' - GCell grid: [%dx%d]' % (columns,rows) UpdateSession.open() - abutmentBox = Box( DbU.fromLambda(0) - , DbU.fromLambda(0) - , DbU.fromLambda(columns*sliceHeight) - , DbU.fromLambda(rows *sliceHeight) - ) - cell.setAbutmentBox( abutmentBox ) + etesian = Etesian.EtesianEngine.create( cell ) + etesian.setDefaultAb() + etesian.destroy() + + #abutmentBox = Box( DbU.fromLambda(0) + # , DbU.fromLambda(0) + # , DbU.fromLambda(columns*sliceHeight) + # , DbU.fromLambda(rows *sliceHeight) + # ) + #cell.setAbutmentBox( abutmentBox ) UpdateSession.close() - return abutmentBox + return cell.getAbutmentBox() diff --git a/etesian/src/BloatCells.cpp b/etesian/src/BloatCells.cpp new file mode 100644 index 00000000..76ee28c4 --- /dev/null +++ b/etesian/src/BloatCells.cpp @@ -0,0 +1,119 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | E t e s i a n - A n a l y t i c P l a c e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./BloatCells.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Cell.h" +#include "etesian/EtesianEngine.h" + + +namespace Etesian { + + using std::cerr; + using std::endl; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::DbU; + + + BloatCell::BloatCell ( std::string name ) + : _name(name) + { } + + + BloatCell::~BloatCell () + { } + + + BloatKey::BloatKey ( string key ) + : BloatCell(key) + { } + + + BloatKey::~BloatKey () + { } + + + DbU::Unit BloatKey::getDx ( const Cell*, const EtesianEngine* ) const + { + cerr << Error( "BloatKey::getAb() must never be called (\"%s\").", getName().c_str() ) << endl; + return 0; + } + + + BloatDisabled::BloatDisabled () + : BloatCell("disabled") + { } + + + BloatDisabled::~BloatDisabled () + { } + + + DbU::Unit BloatDisabled::getDx ( const Cell* cell, const EtesianEngine* ) const + { return 0; } + + + BloatNsxlib::BloatNsxlib () + : BloatCell("nsxlib") + { } + + + BloatNsxlib::~BloatNsxlib () + { } + + + DbU::Unit BloatNsxlib::getDx ( const Cell* cell, const EtesianEngine* etesian ) const + { + Box ab ( cell->getAbutmentBox() ); + DbU::Unit vpitch = etesian->getVerticalPitch();; + int xsize = (ab.getWidth() + vpitch - 1) / vpitch; + + if (xsize < 6) return vpitch*2; + + return 0; + } + + + bool BloatCells::select ( std::string profile ) + { + BloatKey key ( profile ); + + auto ibloat = _bloatCells.find( &key ); + if (ibloat != _bloatCells.end()) { + _selected = *ibloat; + return true; + } + + cerr << Warning( "BloatCells::select(): No profile named \"%s\", using \"disabled\"." + , profile.c_str() + ) << endl; + + return select( "disabled" ); + } + + + Box BloatCells::getAb ( const Cell* cell ) + { + DbU::Unit dx = _selected->getDx( cell, _etesian ); + + _dxSpace += dx; + Box ab = cell->getAbutmentBox(); + return ab.inflate( 0, 0, dx, 0 ); + } + + +} // Etesian namespace. diff --git a/etesian/src/CMakeLists.txt b/etesian/src/CMakeLists.txt index 6b1dfaef..14e0fb84 100644 --- a/etesian/src/CMakeLists.txt +++ b/etesian/src/CMakeLists.txt @@ -12,6 +12,7 @@ ) set( includes etesian/Configuration.h etesian/FeedCells.h + etesian/BloatCells.h etesian/EtesianEngine.h etesian/GraphicEtesianEngine.h ) @@ -22,6 +23,7 @@ set( cpps Configuration.cpp AddFeeds.cpp FeedCells.cpp + BloatCells.cpp EtesianEngine.cpp GraphicEtesianEngine.cpp ) diff --git a/etesian/src/Configuration.cpp b/etesian/src/Configuration.cpp index d1170df0..06b72e3c 100644 --- a/etesian/src/Configuration.cpp +++ b/etesian/src/Configuration.cpp @@ -60,6 +60,7 @@ namespace Etesian { , _spaceMargin ( Cfg::getParamPercentage("etesian.spaceMargin" , 5.0)->asDouble() ) , _aspectRatio ( Cfg::getParamPercentage("etesian.aspectRatio" ,100.0)->asDouble() ) , _feedNames ( Cfg::getParamString ("etesian.feedNames" ,"tie_x0,rowend_x0")->asString() ) + , _bloat ( Cfg::getParamString ("etesian.bloat" ,"disabled" )->asString() ) { string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); if (cg == NULL) { @@ -88,6 +89,7 @@ namespace Etesian { , _spaceMargin ( other._spaceMargin ) , _aspectRatio ( other._aspectRatio ) , _feedNames ( other._feedNames ) + , _bloat ( other._bloat ) { if (other._rg) _rg = other._rg->getClone(); if (other._cg) _cg = other._cg->getClone(); @@ -114,6 +116,7 @@ namespace Etesian { cmess1 << Dots::asBool (" - Routing driven",_routingDriven) << endl; cmess1 << Dots::asPercentage(" - Space Margin" ,_spaceMargin ) << endl; cmess1 << Dots::asPercentage(" - Aspect Ratio" ,_aspectRatio ) << endl; + cmess1 << Dots::asString (" - Bloat model" ,_bloat ) << endl; } @@ -141,6 +144,8 @@ namespace Etesian { record->add ( getSlot( "_spreadingConf" , (int)_spreadingConf ) ); record->add ( getSlot( "_spaceMargin" , _spaceMargin ) ); record->add ( getSlot( "_aspectRatio" , _aspectRatio ) ); + record->add ( getSlot( "_feedNames" , _feedNames ) ); + record->add ( getSlot( "_bloat" , _bloat ) ); return record; } diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 204dacc6..7e64703a 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -48,7 +48,6 @@ #include "crlcore/Measures.h" #include "crlcore/AllianceFramework.h" #include "etesian/EtesianEngine.h" -#include "etesian/FeedCells.h" namespace { @@ -265,6 +264,7 @@ namespace Etesian { , _idsToInsts () , _viewer (NULL) , _feedCells (this) + , _bloatCells (this) { } @@ -278,6 +278,8 @@ namespace Etesian { cmess2 << " o ISPD benchmark <" << getCell()->getName() << ">, no feed cells will be added." << endl; } else { + _bloatCells.select( getConfiguration()->getBloat() ); + string feedNames = getConfiguration()->getFeedNames(); char separator = ','; @@ -349,6 +351,7 @@ namespace Etesian { void EtesianEngine::setDefaultAb () { + _bloatCells.resetDxSpace(); double spaceMargin = getSpaceMargin(); double aspectRatio = getAspectRatio(); size_t instanceNb = 0; @@ -369,10 +372,13 @@ namespace Etesian { continue; } - cellLength += DbU::toLambda( masterCell->getAbutmentBox().getWidth() ); + cellLength += DbU::toLambda( _bloatCells.getAb( masterCell ).getWidth() ); instanceNb += 1; } + double bloatLength = DbU::toLambda( _bloatCells.getDxSpace() ); + double bloatMargin = ( cellLength / (cellLength - bloatLength) ) - 1.0; + double gcellLength = cellLength*(1.0+spaceMargin) / DbU::toLambda( getSliceHeight() ); double rows = std::ceil( sqrt( gcellLength/aspectRatio ) ); double columns = std::ceil( gcellLength / rows ); @@ -398,6 +404,8 @@ namespace Etesian { << "% aspect ratio:" << (aspectRatio*100.0) << "% g-length:" << (cellLength/DbU::toLambda(getSliceHeight())) << ")" << endl; + cmess1 << " - Bloat space margin: " + << setprecision(4) << (bloatMargin*100.0) << "%." << endl; cmess1 << " - " << getCell()->getAbutmentBox() << endl; cmess1 << " - GCell grid: [" << (int)columns << "x" << (int)rows << "]" << endl; } @@ -538,7 +546,7 @@ namespace Etesian { continue; } - Box instanceAb = masterCell->getAbutmentBox(); + Box instanceAb = _bloatCells.getAb( masterCell ); Transformation instanceTransf = instance->getTransformation(); occurrence.getPath().getTransformation().applyOn( instanceTransf ); @@ -551,6 +559,8 @@ namespace Etesian { int_t xpos = instanceAb.getXMin() / vpitch; int_t ypos = instanceAb.getYMin() / hpitch; + //if (xsize < 6) xsize += 2; + // if ( (ysize != 1) and not instance->isFixed() ) { // cerr << Error( "EtesianEngine::toColoquinte(): Instance \"%s\" of \"%s\" is a block (height: %d)." // , instanceName.c_str() @@ -558,6 +568,9 @@ namespace Etesian { // , ysize ) << endl; // } + // cerr << instance << " size:(" << xsize << " " << ysize + // << ") pos:(" << xpos << " " << ypos << ")" << endl; + instances[instanceId].size = point( xsize, ysize ); instances[instanceId].list_index = instanceId; instances[instanceId].area = static_cast(xsize) * static_cast(ysize); @@ -603,6 +616,8 @@ namespace Etesian { nets[netId] = temporary_net( netId, 1 ); + //cerr << "+ " << net << endl; + for ( RoutingPad* rp : net->getRoutingPads() ) { string insName = extractInstanceName( rp ); Point offset = extractRpOffset ( rp ); @@ -616,6 +631,8 @@ namespace Etesian { } else { pins.push_back( temporary_pin( point(xpin,ypin), (*iid).second, netId ) ); } + + //cerr << "| " << rp << " pos:(" << xpin << " " << ypin << ")" << endl; } netId++; diff --git a/etesian/src/PyEtesianEngine.cpp b/etesian/src/PyEtesianEngine.cpp index 5378772d..aff4b959 100644 --- a/etesian/src/PyEtesianEngine.cpp +++ b/etesian/src/PyEtesianEngine.cpp @@ -63,6 +63,9 @@ extern "C" { // +=================================================================+ + DirectVoidMethod(EtesianEngine,etesian,setDefaultAb) + + static PyObject* PyEtesianEngine_get ( PyObject*, PyObject* args ) { cdebug_log(34,0) << "PyEtesianEngine_get()" << endl; @@ -127,6 +130,25 @@ extern "C" { } + static PyObject* PyEtesianEngine_selectBloat ( PyEtesianEngine* self, PyObject* args ) + { + cdebug_log(34,0) << "PyEtesianEngine_selectBloat ()" << endl; + + HTRY + METHOD_HEAD( "EtesianEngine.selectBloat()" ) + + const char* profile = NULL; + if (not PyArg_ParseTuple(args,"s:EtesianEngine.selectBloat()",&profile)) { + PyErr_SetString( ConstructorError, "Bad parameters given to EtesianEngine.selectBloat()." ); + return NULL; + } + etesian->selectBloat( profile ); + HCATCH + + Py_RETURN_NONE; + } + + static PyObject* PyEtesianEngine_place ( PyEtesianEngine* self ) { cdebug_log(34,0) << "PyEtesianEngine_place()" << endl; @@ -159,6 +181,10 @@ extern "C" { , "Create an Etesian engine on this cell." } , { "setViewer" , (PyCFunction)PyEtesianEngine_setViewer , METH_VARARGS , "Associate a Viewer to this EtesianEngine." } + , { "selectBloat" , (PyCFunction)PyEtesianEngine_selectBloat , METH_VARARGS + , "Select the Cell bloating profile." } + , { "setDefaultAb" , (PyCFunction)PyEtesianEngine_setDefaultAb , METH_NOARGS + , "Compute and set the abutment box using the aspect ratio and the space margin." } , { "place" , (PyCFunction)PyEtesianEngine_place , METH_NOARGS , "Run the placer (Etesian)." } , { "destroy" , (PyCFunction)PyEtesianEngine_destroy , METH_NOARGS diff --git a/etesian/src/etesian/BloatCells.h b/etesian/src/etesian/BloatCells.h new file mode 100644 index 00000000..6dbc929d --- /dev/null +++ b/etesian/src/etesian/BloatCells.h @@ -0,0 +1,127 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | E t e s i a n - A n a l y t i c P l a c e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./etesian/BloatCells.h" | +// +-----------------------------------------------------------------+ + + +#ifndef ETESIAN_BLOATCELLS_H +#define ETESIAN_BLOATCELLS_H + +#include +#include "hurricane/Box.h" +#include "hurricane/Cell.h" + + +namespace Etesian { + + using Hurricane::Box; + using Hurricane::Cell; + class EtesianEngine; + + + class BloatCell { + public: + class Compare { + public: + inline bool operator() ( const BloatCell* lhs, BloatCell* rhs ) const; + inline bool operator() ( std::string lhs, BloatCell* rhs ) const; + inline bool operator() ( const BloatCell* lhs, std::string rhs ) const; + }; + public: + BloatCell ( std::string ); + virtual ~BloatCell (); + virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const = 0; + inline std::string getName () const; + private: + std::string _name; + }; + + + inline bool BloatCell::Compare::operator() ( const BloatCell* lhs, BloatCell* rhs ) const + { return (lhs->getName() < rhs->getName()); } + + inline bool BloatCell::Compare::operator() ( std::string lhs, BloatCell* rhs ) const + { return (lhs < rhs->getName()); } + + inline bool BloatCell::Compare::operator() ( const BloatCell* lhs, std::string rhs ) const + { return (lhs->getName() < rhs); } + + + inline std::string BloatCell::getName () const { return _name; } + + + class BloatKey : public BloatCell { + public: + BloatKey ( std::string ); + virtual ~BloatKey (); + virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const; + }; + + + class BloatDisabled : public BloatCell { + public: + BloatDisabled (); + virtual ~BloatDisabled (); + virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const; + }; + + + class BloatNsxlib : public BloatCell { + public: + BloatNsxlib (); + virtual ~BloatNsxlib (); + virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const; + }; + + + class BloatCells { + public: + inline BloatCells ( EtesianEngine* ); + inline ~BloatCells (); + bool select ( std::string ); + Box getAb ( const Cell* ); + inline DbU::Unit getDxSpace () const; + inline void resetDxSpace (); + private: + EtesianEngine* _etesian; + BloatCell* _selected; + std::set _bloatCells; + DbU::Unit _dxSpace; + }; + + + inline BloatCells::BloatCells ( EtesianEngine* etesian ) + : _etesian (etesian) + , _selected (NULL) + , _bloatCells() + , _dxSpace (0) + { + _bloatCells.insert( new BloatDisabled() ); + _bloatCells.insert( new BloatNsxlib () ); + select( "disabled" ); + } + + + inline BloatCells::~BloatCells () + { + for ( BloatCell* bloat : _bloatCells ) delete bloat; + } + + + inline DbU::Unit BloatCells::getDxSpace () const { return _dxSpace; } + inline void BloatCells::resetDxSpace () { _dxSpace = 0; } + + +} // Etesian namespace. + +#endif // ETESIAN_BLOATCELLS_H diff --git a/etesian/src/etesian/Configuration.h b/etesian/src/etesian/Configuration.h index 556f7220..a36c21b9 100644 --- a/etesian/src/etesian/Configuration.h +++ b/etesian/src/etesian/Configuration.h @@ -73,6 +73,7 @@ namespace Etesian { inline double getSpaceMargin () const; inline double getAspectRatio () const; inline string getFeedNames () const; + inline string getBloat () const; void print ( Cell* ) const; Record* _getRecord () const; string _getString () const; @@ -88,6 +89,7 @@ namespace Etesian { double _spaceMargin; double _aspectRatio; string _feedNames; + string _bloat; private: Configuration ( const Configuration& ); Configuration& operator= ( const Configuration& ); @@ -103,6 +105,7 @@ namespace Etesian { inline double Configuration::getSpaceMargin () const { return _spaceMargin; } inline double Configuration::getAspectRatio () const { return _aspectRatio; } inline string Configuration::getFeedNames () const { return _feedNames; } + inline string Configuration::getBloat () const { return _bloat; } } // Etesian namespace. diff --git a/etesian/src/etesian/EtesianEngine.h b/etesian/src/etesian/EtesianEngine.h index b992ce31..f246530d 100644 --- a/etesian/src/etesian/EtesianEngine.h +++ b/etesian/src/etesian/EtesianEngine.h @@ -35,6 +35,7 @@ namespace Hurricane { #include "crlcore/ToolEngine.h" #include "etesian/Configuration.h" #include "etesian/FeedCells.h" +#include "etesian/BloatCells.h" namespace Etesian { @@ -92,6 +93,7 @@ namespace Etesian { inline void useFeed ( Cell* ); size_t findYSpin (); void addFeeds (); + inline void selectBloat ( std::string ); virtual Record* _getRecord () const; virtual std::string _getString () const; virtual std::string _getTypeName () const; @@ -112,6 +114,7 @@ namespace Etesian { std::vector _idsToInsts; Hurricane::CellViewer* _viewer; FeedCells _feedCells; + BloatCells _bloatCells; size_t _yspinSlice0; protected: @@ -146,6 +149,7 @@ namespace Etesian { inline double EtesianEngine::getAspectRatio () const { return getConfiguration()->getAspectRatio(); } inline void EtesianEngine::useFeed ( Cell* cell ) { _feedCells.useFeed(cell); } inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; } + inline void EtesianEngine::selectBloat ( std::string profile ) { _bloatCells.select(profile); } // Variables. diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 0918b0b9..6d9683d5 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -1528,7 +1528,7 @@ Name Cell::InstanceMap::_getKey(Instance* instance) const unsigned int Cell::InstanceMap::_getHashValue(Name name) const // ******************************************************* { - return name._getSharedName()->getId() / 8; + return name._getSharedName()->getHash() / 8; } Instance* Cell::InstanceMap::_getNextElement(Instance* instance) const @@ -1643,7 +1643,7 @@ Name Cell::PinMap::_getKey(Pin* pin) const unsigned Cell::PinMap::_getHashValue(Name name) const // ************************************************** { - return (unsigned int)name._getSharedName()->getId() / 8; + return (unsigned int)name._getSharedName()->getHash() / 8; } Pin* Cell::PinMap::_getNextElement(Pin* pin) const diff --git a/hurricane/src/hurricane/HyperNet.cpp b/hurricane/src/hurricane/HyperNet.cpp index 9f7c220f..547f7d08 100644 --- a/hurricane/src/hurricane/HyperNet.cpp +++ b/hurricane/src/hurricane/HyperNet.cpp @@ -602,65 +602,66 @@ static bool IsConnex(const Occurrence& componentOccurrence1, const Occurrence& c } void HyperNet_NetOccurrences::Locator::progress() -// ********************************************* +// ********************************************** { - if (!_netOccurrenceStack.empty()) { - Occurrence netOccurrence = _netOccurrenceStack.top(); - _netOccurrenceStack.pop(); - Net* net = (Net*)netOccurrence.getEntity(); - Path path = netOccurrence.getPath(); + if (not _netOccurrenceStack.empty()) { + Occurrence netOccurrence = _netOccurrenceStack.top(); + _netOccurrenceStack.pop(); + Net* net = (Net*)netOccurrence.getEntity(); + Path path = netOccurrence.getPath(); - if (_doExtraction) { - Cell* cell = netOccurrence.getOwnerCell(); - for_each_component(component, net->getComponents()) { - if (!dynamic_cast(component)) { - //if (_allowInterruption && !((i++) % 200)) gtk_check_for_interruption(); - Occurrence occurrence = Occurrence(component, path); - Box area = occurrence.getBoundingBox(); - for_each_occurrence(occurrence2, cell->getOccurrencesUnder(area)) { - if (dynamic_cast(occurrence2.getEntity())) { - Component* component2 = (Component*)occurrence2.getEntity(); - if (IsConnex(occurrence, occurrence2)) { - Occurrence net2Occurrence = - Occurrence(component2->getNet(), occurrence2.getPath()); - if (_netOccurrenceSet.find(net2Occurrence) == _netOccurrenceSet.end()) { - _netOccurrenceSet.insert(net2Occurrence); - _netOccurrenceStack.push(net2Occurrence); - } - } - } - end_for; - } + if (_doExtraction) { + Cell* cell = netOccurrence.getOwnerCell(); + for ( Component* component : net->getComponents()) { + if (not dynamic_cast(component)) { + //if (_allowInterruption && !((i++) % 200)) gtk_check_for_interruption(); + Occurrence occurrence = Occurrence( component, path ); + Box area = occurrence.getBoundingBox(); + + for ( Occurrence occurrence2 : cell->getOccurrencesUnder(area)) { + if (dynamic_cast(occurrence2.getEntity())) { + Component* component2 = static_cast( occurrence2.getEntity() ); + + if (IsConnex(occurrence,occurrence2)) { + Occurrence net2Occurrence = + Occurrence( component2->getNet(), occurrence2.getPath() ); + + if (_netOccurrenceSet.find(net2Occurrence) == _netOccurrenceSet.end()) { + _netOccurrenceSet.insert(net2Occurrence); + _netOccurrenceStack.push(net2Occurrence); + } } - end_for; - } - } + } + } // for occurence2. + } + } // for component*. + } - for_each_plug(plug, net->getPlugs()) { - Occurrence occurrence = Occurrence(plug->getMasterNet(), Path(path, plug->getInstance())); - if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) { + for ( Plug* plug : net->getPlugs() ) { + Occurrence occurrence = Occurrence( plug->getMasterNet(), Path(path, plug->getInstance()) ); + + if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) { + _netOccurrenceSet.insert(occurrence); + _netOccurrenceStack.push(occurrence); + } + } + + if (net->isExternal()) { + Instance* instance = path.getTailInstance(); + if (instance) { + Plug* plug = instance->getPlug(net); + if (plug) { + Net* net = plug->getNet(); + if (net) { + Occurrence occurrence = Occurrence(net, path.getHeadPath()); + if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) { _netOccurrenceSet.insert(occurrence); _netOccurrenceStack.push(occurrence); + } } - end_for; - } - - if (net->isExternal()) { - Instance* instance = path.getTailInstance(); - if (instance) { - Plug* plug = instance->getPlug(net); - if (plug) { - Net* net = plug->getNet(); - if (net) { - Occurrence occurrence = Occurrence(net, path.getHeadPath()); - if (_netOccurrenceSet.find(occurrence) == _netOccurrenceSet.end()) { - _netOccurrenceSet.insert(occurrence); - _netOccurrenceStack.push(occurrence); - } - } - } - } + } } + } // if net->isExternal(). } } @@ -1053,6 +1054,7 @@ void HyperNet_LeafPlugOccurrences::Locator::progress() while(_netOccurrenceLocator.isValid() && !_plugOccurrence.isValid()) { Occurrence netOccurrence = _netOccurrenceLocator.getElement(); + _netOccurrenceLocator.progress(); Net* net = (Net*)netOccurrence.getEntity(); Path path = netOccurrence.getPath(); diff --git a/hurricane/src/hurricane/Instance.cpp b/hurricane/src/hurricane/Instance.cpp index bd5f7c6e..ffaf295d 100644 --- a/hurricane/src/hurricane/Instance.cpp +++ b/hurricane/src/hurricane/Instance.cpp @@ -709,7 +709,7 @@ const SharedPath* Instance::SharedPathMap::_getKey(SharedPath* sharedPath) const unsigned Instance::SharedPathMap::_getHashValue(const SharedPath* tailSharedPath) const // ************************************************************************************ { - return (tailSharedPath) ? (tailSharedPath->getId()/8) : 0; + return (tailSharedPath) ? (tailSharedPath->getHash()/8) : 0; } SharedPath* Instance::SharedPathMap::_getNextElement(SharedPath* sharedPath) const diff --git a/hurricane/src/hurricane/Library.cpp b/hurricane/src/hurricane/Library.cpp index b01b495a..708d78c1 100644 --- a/hurricane/src/hurricane/Library.cpp +++ b/hurricane/src/hurricane/Library.cpp @@ -178,7 +178,7 @@ Name Library::LibraryMap::_getKey(Library* library) const unsigned Library::LibraryMap::_getHashValue(Name name) const // ********************************************************* { - return name._getSharedName()->getId() / 8; + return name._getSharedName()->getHash() / 8; } Library* Library::LibraryMap::_getNextElement(Library* library) const @@ -214,7 +214,7 @@ Name Library::CellMap::_getKey(Cell* cell) const unsigned Library::CellMap::_getHashValue(Name name) const // ****************************************************** { - return name._getSharedName()->getId() / 8; + return name._getSharedName()->getHash() / 8; } Cell* Library::CellMap::_getNextElement(Cell* cell) const diff --git a/hurricane/src/hurricane/Occurrence.cpp b/hurricane/src/hurricane/Occurrence.cpp index b6a84473..be6b2deb 100644 --- a/hurricane/src/hurricane/Occurrence.cpp +++ b/hurricane/src/hurricane/Occurrence.cpp @@ -99,7 +99,7 @@ bool Occurrence::operator<(const Occurrence& occurrence) const if (not _sharedPath) return true; if (not occurrence._sharedPath) return false; - return _sharedPath->getId() < occurrence._sharedPath->getId(); + return _sharedPath->getHash() < occurrence._sharedPath->getHash(); //return ((_entity < occurrence._entity) or // ((_entity == occurrence._entity) and (_sharedPath < occurrence._sharedPath))); diff --git a/hurricane/src/hurricane/SharedName.cpp b/hurricane/src/hurricane/SharedName.cpp index ca6e9e59..068ee093 100644 --- a/hurricane/src/hurricane/SharedName.cpp +++ b/hurricane/src/hurricane/SharedName.cpp @@ -30,21 +30,23 @@ namespace Hurricane { // **************************************************************************************************** SharedName::SharedNameMap* SharedName::_SHARED_NAME_MAP = NULL; - unsigned int SharedName::_idCounter = 0; SharedName::SharedName ( const string& name ) - : _id (_idCounter++) + : _hash (0) , _count (0) , _string(name) { if (!_SHARED_NAME_MAP) _SHARED_NAME_MAP = new SharedNameMap(); (*_SHARED_NAME_MAP)[&_string] = this; - if (_idCounter == std::numeric_limits::max()) { - throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)." - , std::numeric_limits::digits ); - } + for ( char c : _string ) _hash = 131 * _hash + int(c); + + // if (_idCounter == std::numeric_limits::max()) { + // throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)." + // , std::numeric_limits::digits ); + // } + cdebug_log(0,0) << "SharedName::SharedName() hash:" << _hash << " \"" << _string << "\"" << endl; } @@ -69,7 +71,7 @@ void SharedName::release() string SharedName::_getString() const // ********************************** { - return "<" + _TName("SharedName") + " " + getString(_count) + " id:" + getString(_id) + " " + _string + ">"; + return "<" + _TName("SharedName") + " " + getString(_count) + " hash:" + getString(_hash) + " " + _string + ">"; } Record* SharedName::_getRecord() const diff --git a/hurricane/src/hurricane/SharedPath.cpp b/hurricane/src/hurricane/SharedPath.cpp index bda87bae..12dc8b31 100644 --- a/hurricane/src/hurricane/SharedPath.cpp +++ b/hurricane/src/hurricane/SharedPath.cpp @@ -98,22 +98,15 @@ class SharedPath_Instances : public Collection { // **************************************************************************************************** static char NAME_SEPARATOR = '.'; -unsigned int SharedPath::_idCounter = 0; SharedPath::SharedPath(Instance* headInstance, SharedPath* tailSharedPath) // *********************************************************************** - : _id(_idCounter++), - _headInstance(headInstance), + : _headInstance(headInstance), _tailSharedPath(tailSharedPath), _quarkMap(), _nextOfInstanceSharedPathMap(NULL) { - if (_idCounter == std::numeric_limits::max()) { - throw Error( "SharedName::SharedName(): Identifier counter has reached it's limit (%d bits)." - , std::numeric_limits::digits ); - } - if (!_headInstance) throw Error("Can't create " + _TName("SharedPath") + " : null head instance"); @@ -134,6 +127,8 @@ SharedPath::SharedPath(Instance* headInstance, SharedPath* tailSharedPath) ); _headInstance->_getSharedPathMap()._insert(this); + + cdebug_log(0,0) << "SharedPath::SharedPath() pathHash:" << getHash() << " \"" << this << "\"" << endl; } SharedPath::~SharedPath() @@ -190,6 +185,10 @@ string SharedPath::getName() const return name; } +unsigned long SharedPath::getHash() const +// *************************************** +{ return (_headInstance->getId() << 1) + ((_tailSharedPath) ? _tailSharedPath->getHash() << 1: 0); } + string SharedPath::getJsonString(unsigned long flags) const // ******************************************************** { diff --git a/hurricane/src/hurricane/Technology.cpp b/hurricane/src/hurricane/Technology.cpp index 32ec4e0e..5d717553 100644 --- a/hurricane/src/hurricane/Technology.cpp +++ b/hurricane/src/hurricane/Technology.cpp @@ -738,7 +738,7 @@ namespace Hurricane { unsigned Technology::LayerMap::_getHashValue ( Name name ) const - { return name._getSharedName()->getId() / 8; } + { return name._getSharedName()->getHash() / 8; } Layer* Technology::LayerMap::_getNextElement ( Layer* layer ) const diff --git a/hurricane/src/hurricane/hurricane/SharedName.h b/hurricane/src/hurricane/hurricane/SharedName.h index 0e3e639c..4983994e 100644 --- a/hurricane/src/hurricane/hurricane/SharedName.h +++ b/hurricane/src/hurricane/hurricane/SharedName.h @@ -33,18 +33,18 @@ namespace Hurricane { friend class Name; public: - inline unsigned int getId () const; - const string& _getSString () const { return _string; }; - string _getTypeName () const { return _TName("SharedName"); }; - string _getString () const; - Record* _getRecord () const; - private: - SharedName ( const string& ); - SharedName ( const SharedName& ); - ~SharedName (); - SharedName& operator= ( const SharedName& ); - void capture (); - void release (); + inline unsigned long getHash () const; + const string& _getSString () const { return _string; }; + string _getTypeName () const { return _TName("SharedName"); }; + string _getString () const; + Record* _getRecord () const; + private: + SharedName ( const string& ); + SharedName ( const SharedName& ); + ~SharedName (); + SharedName& operator= ( const SharedName& ); + void capture (); + void release (); private: struct SharedNameMapComparator { @@ -54,14 +54,13 @@ namespace Hurricane { private: static SharedNameMap* _SHARED_NAME_MAP; - static unsigned int _idCounter; - unsigned int _id; + unsigned long _hash; int _count; string _string; }; - inline unsigned int SharedName::getId () const { return _id; } + inline unsigned long SharedName::getHash () const { return _hash; } } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/SharedPath.h b/hurricane/src/hurricane/hurricane/SharedPath.h index d03659fa..4e799bf8 100644 --- a/hurricane/src/hurricane/hurricane/SharedPath.h +++ b/hurricane/src/hurricane/hurricane/SharedPath.h @@ -60,8 +60,6 @@ class SharedPath { // Attributes // ********** - private: static unsigned int _idCounter; - private: unsigned int _id; private: Instance* _headInstance; private: SharedPath* _tailSharedPath; private: QuarkMap _quarkMap; @@ -91,7 +89,7 @@ class SharedPath { public: static char getNameSeparator(); - public: unsigned int getId() const { return _id; } + public: unsigned long getHash() const; public: Instance* getHeadInstance() const {return _headInstance;}; public: SharedPath* getTailSharedPath() const {return _tailSharedPath;}; public: SharedPath* getHeadSharedPath() const; diff --git a/hurricane/src/isobar/PyVertical.cpp b/hurricane/src/isobar/PyVertical.cpp index 744355aa..9ff8f156 100644 --- a/hurricane/src/isobar/PyVertical.cpp +++ b/hurricane/src/isobar/PyVertical.cpp @@ -10,7 +10,7 @@ // | Author : Sophie BELLOEIL | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Module : "./PyCell.cpp" | +// | C++ Module : "./PyVertical.cpp" | // +-----------------------------------------------------------------+ diff --git a/katana/src/CMakeLists.txt b/katana/src/CMakeLists.txt index e416bdeb..f201e87c 100644 --- a/katana/src/CMakeLists.txt +++ b/katana/src/CMakeLists.txt @@ -18,6 +18,7 @@ katana/TrackElement.h katana/TrackElements.h katana/TrackSegment.h katana/TrackSegmentRegular.h + katana/TrackSegmentNonPref.h katana/TrackSegmentWide.h katana/TrackFixedSegment.h katana/TrackMarker.h @@ -53,6 +54,7 @@ TrackElements.cpp TrackSegment.cpp TrackSegmentRegular.cpp + TrackSegmentNonPref.cpp TrackSegmentWide.cpp TrackFixedSegment.cpp TrackMarker.cpp diff --git a/katana/src/Configuration.cpp b/katana/src/Configuration.cpp index 99663b7f..6693bcb5 100644 --- a/katana/src/Configuration.cpp +++ b/katana/src/Configuration.cpp @@ -151,7 +151,7 @@ namespace Katana { cout << Dots::asUInt (" - Global router H reserved local" ,_hTracksReservedLocal) << endl; cout << Dots::asUInt (" - Global router V reserved local" ,_vTracksReservedLocal) << endl; cout << Dots::asULong(" - Events limit (iterations)" ,_eventsLimit) << endl; - cout << Dots::asUInt (" - Ripup limit, straps" ,_ripupLimits[StrapRipupLimit]) << endl; + cout << Dots::asUInt (" - Ripup limit, straps & unbreakables" ,_ripupLimits[StrapRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, locals" ,_ripupLimits[LocalRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, globals" ,_ripupLimits[GlobalRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, long globals" ,_ripupLimits[LongGlobalRipupLimit]) << endl; @@ -183,10 +183,10 @@ namespace Katana { record->add ( getSlot("_ripupCost" ,_ripupCost ) ); record->add ( getSlot("_eventsLimit" ,_eventsLimit ) ); - record->add ( getSlot("_ripupLimits[StrapRipupLimit]" ,_ripupLimits[StrapRipupLimit] ) ); - record->add ( getSlot("_ripupLimits[LocalRipupLimit]" ,_ripupLimits[LocalRipupLimit] ) ); - record->add ( getSlot("_ripupLimits[GlobalRipupLimit]" ,_ripupLimits[GlobalRipupLimit] ) ); - record->add ( getSlot("_ripupLimits[LongGlobalRipupLimit]",_ripupLimits[LongGlobalRipupLimit]) ); + record->add ( getSlot("_ripupLimits[StrapRipupLimit]" ,_ripupLimits[StrapRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[LocalRipupLimit]" ,_ripupLimits[LocalRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[GlobalRipupLimit]" ,_ripupLimits[GlobalRipupLimit] ) ); + record->add ( getSlot("_ripupLimits[LongGlobalRipupLimit]" ,_ripupLimits[LongGlobalRipupLimit]) ); // for ( size_t i=0 ; igetTrack()) { + + if (perpandicular->isNonPref()) { + AutoContact* source = perpandicular->base()->getAutoSource(); + AutoContact* target = perpandicular->base()->getAutoTarget(); + DbU::Unit pitch = Session::getPitch ( perpandicular->getLayer() ); + Flags direction = Session::getDirection( perpandicular->getLayer() ); + Interval trackFree ( false ); + + if (source->canDrag()) { + if (direction & Flags::Horizontal) + trackFree.intersection( source->getCBYMin(), source->getCBYMax() ); + else + trackFree.intersection( source->getCBXMin(), source->getCBXMax() ); + cdebug_log(159,0) << "trackFree (source drag): " << trackFree << endl; + } + if (target->canDrag()) { + if (direction & Flags::Horizontal) + trackFree.intersection( target->getCBYMin(), target->getCBYMax() ); + else + trackFree.intersection( target->getCBXMin(), target->getCBXMax() ); + cdebug_log(159,0) << "trackFree (target drag): " << trackFree << endl; + } + + if (not source->canDrag() and not target->canDrag()) + perpandicular->base()->getCanonical( trackFree ); + + trackFree.inflate( 1*pitch, 1*pitch ); + cdebug_log(159,0) << "Non-Pref Track Perpandicular Free: " << trackFree << endl; + + //_perpandicularFree.intersection + // ( trackFree.inflate ( pitch - perpandicular->getExtensionCap(Flags::Source) + // , pitch - perpandicular->getExtensionCap(Flags::Target)) ); + _perpandicularFree.intersection( trackFree ); + } else if (perpandicular->getTrack()) { Interval trackFree = perpandicular->getFreeInterval(); cdebug_log(159,0) << "Track Perpandicular Free: " << trackFree << endl; diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index 36155378..6a80c101 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -63,11 +63,16 @@ namespace { inline void DigitalDistance::setNet ( Net* net ) { _net = net; } - DbU::Unit DigitalDistance::operator() ( const Vertex* source ,const Vertex* target,const Edge* edge ) const + DbU::Unit DigitalDistance::operator() ( const Vertex* source, const Vertex* target, const Edge* edge ) const { if (source->getGCell()->isStdCellRow() and target->getGCell()->isStdCellRow()) return Vertex::unreachable; + if ( source->getGCell()->isGoStraight() + and source->getFrom() + and (source->getFrom()->isHorizontal() xor edge->isHorizontal())) + return Vertex::unreachable; + if (edge->getCapacity() <= 0) { if (target->getGCell()->isStdCellRow() and target->hasValidStamp() and (target->getConnexId() >= 0) ) @@ -117,7 +122,8 @@ namespace { << DbU::getValueString(source->getDistance()) << " + (" << congestionCost << " + " << viaCost << " + " - << edge->getHistoricCost() << ") * " + //<< edge->getHistoricCost() << ") * " + << historicCost << ") * " << DbU::getValueString(edgeDistance) << " * " << hvScaling << endl; @@ -312,12 +318,12 @@ namespace Katana { openSession(); annotateGlobalGraph(); - for ( NetData* netData : getNetOrdering() ) { - if (netData->isGlobalRouted() or netData->isExcluded()) continue; + // for ( NetData* netData : getNetOrdering() ) { + // if (netData->isGlobalRouted() or netData->isExcluded()) continue; - updateEstimateDensity( netData, 1.0 ); - netData->setGlobalEstimated( true ); - } + // updateEstimateDensity( netData, 1.0 ); + // netData->setGlobalEstimated( true ); + // } // Session::close(); // Breakpoint::stop( 1, "After global routing estimation." ); @@ -339,9 +345,12 @@ namespace Katana { if (isChannelMode()) dijkstra->setSearchAreaHalo( Session::getSliceHeight()*10 ); + else + dijkstra->setSearchAreaHalo( Session::getSliceHeight()*1 ); - size_t iteration = 0; - size_t netCount = 0; + bool globalEstimated = false; + size_t iteration = 0; + size_t netCount = 0; do { cmess2 << " [" << setfill(' ') << setw(3) << iteration << "] nets:"; @@ -359,7 +368,24 @@ namespace Katana { distance->setNet( netData->getNet() ); dijkstra->load( netData->getNet() ); dijkstra->run(); + netData->setGlobalRouted( true ); ++netCount; + + // if (netData->getNet()->getName() == Name("mips_r3000_1m_dp_shift32_rshift_se_msb")) { + // Session::close(); + // Breakpoint::stop( 1, "After global routing of \"mips_r3000_1m_dp_shift32_rshift_se_msb\"." ); + // openSession(); + // } + + if ( (netData->getRpCount() < 11) and not globalEstimated ) { + for ( NetData* netData2 : getNetOrdering() ) { + if (netData2->isGlobalRouted() or netData2->isExcluded()) continue; + + updateEstimateDensity( netData2, 1.0 ); + netData2->setGlobalEstimated( true ); + } + globalEstimated = true; + } } cmess2 << left << setw(6) << netCount; @@ -416,9 +442,11 @@ namespace Katana { cerr << " o Global routing did not complete, overflowed edges:" << endl; for ( size_t iEdge = 0 ; iEdgegetSegments() ) + cerr << " " << dec << setw(4) << (iEdge+1) << "+ " << ovEdges[iEdge] << endl; + for ( Segment* segment : ovEdges[iEdge]->getSegments() ) { + cerr << " | " << segment << " " << DbU::getValueString(segment->getLength()) << endl; nets.insert( segment->getNet() ); + } } cerr << " o Conflicting nets:" << endl; @@ -466,7 +494,7 @@ namespace Katana { } else { if (component->getLayer() == cLayer) { Contact* contact = static_cast( component ); - size_t gslaves = 0; + //size_t gslaves = 0; for ( Component* slave : contact->getSlaveComponents().getSubSet() ) { if (slave->getLayer() == vLayer) { ++viaCount; break; } diff --git a/katana/src/GraphicKatanaEngine.cpp b/katana/src/GraphicKatanaEngine.cpp index c8c954f6..8959eb62 100644 --- a/katana/src/GraphicKatanaEngine.cpp +++ b/katana/src/GraphicKatanaEngine.cpp @@ -243,6 +243,8 @@ namespace Katana { { KatanaEngine* katana = getForFramework( CreateEngine ); katana->runGlobalRouter(); + + //Breakpoint::stop( 0, "GraphicKatanaEngine::_globalRoute() done." ); } @@ -252,6 +254,8 @@ namespace Katana { _viewer->clearToolInterrupt(); katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); + + //Breakpoint::stop( 0, "GraphicKatanaEngine::_loadGlobalRouting() done." ); } @@ -260,6 +264,8 @@ namespace Katana { KatanaEngine* katana = getForFramework( NoFlags ); //katana->balanceGlobalDensity(); katana->layerAssign( Anabatic::EngineNoNetLayerAssign ); + + //Breakpoint::stop( 0, "GraphicKatanaEngine::_balanceGlobalDensity() done." ); } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index aa353894..3795cd4c 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -354,9 +354,10 @@ namespace Katana { { if (segment->isBlockage()) return 0; - if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); - if (segment->isShortNet()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit ); - if (segment->isGlobal()) { + if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isUnbreakable()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isShortNet ()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit ); + if (segment->isGlobal ()) { vector gcells; segment->getGCells( gcells ); if (gcells.size() > 2) @@ -519,7 +520,6 @@ namespace Katana { _negociateWindow = NegociateWindow::create( this ); _negociateWindow->setGCells( getGCells() ); - _computeCagedConstraints(); _negociateWindow->run( flags ); _negociateWindow->destroy(); _negociateWindow = NULL; diff --git a/katana/src/Manipulator.cpp b/katana/src/Manipulator.cpp index c2b45d43..91fc52d6 100644 --- a/katana/src/Manipulator.cpp +++ b/katana/src/Manipulator.cpp @@ -150,6 +150,14 @@ namespace Katana { if (_data == NULL) { cdebug_tabw(159,-1); return true; } _fsm.addAction( _segment, type, axisHint ); + if (_segment->isDrag()) { + set canonicals; + for ( TrackElement* perpand + : _segment->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { + if (not _fsm.hasAction(perpand)) + Manipulator(perpand,_fsm).ripup( SegmentAction::OtherRipup|SegmentAction::EventLevel1 ); + } + } cdebug_tabw(159,-1); return true; } @@ -602,7 +610,7 @@ namespace Katana { TrackElement* segment = Session::lookup(doglegs[i]); if (not segment->getTrack() and track) { cdebug_log(159,0) << "Direct Track insert of: " << segment << endl; - Session::addInsertEvent( segment, track ); + Session::addInsertEvent( segment, track, track->getAxis() ); } } } @@ -650,7 +658,7 @@ namespace Katana { bool Manipulator::insertInTrack ( size_t icost ) { - cdebug_log(159,1) << "Manipulator::insertInTrack(size_t)" << endl; + cdebug_log(159,1) << "Manipulator::insertInTrack(icost)" << endl; cdebug_log(159,0) << _segment << endl; bool success = true; @@ -665,7 +673,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 - , _fsm.getTrack1(icost)->getAxis() ); + , _fsm.getCandidateAxis1(icost) ); #if THIS_IS_DISABLED uint32_t flags = 0; @@ -697,7 +705,7 @@ namespace Katana { //bool rightIntrication = false; bool success = true; - cdebug_log(159,1) << "Manipulator::_insertInTrack(size_t) - " << toFree << endl; + cdebug_log(159,1) << "Manipulator::_insertInTrack(icost,itrack) - " << toFree << endl; cdebug_log(159,0) << _segment << endl; for ( size_t i = begin ; success and (i < end) ; i++ ) { @@ -774,7 +782,8 @@ namespace Katana { } cdebug_log(159,0) << "- Hard overlap/enclosure/shrink " << segment2 << endl; - if ( _segment->isStrap() and segment2->isGlobal() ) continue; + //if ( (_segment->isUnbreakable() or _segment->isStrap()) and segment2->isGlobal() ) continue; + if ( (_segment->isStrap()) and segment2->isGlobal() ) continue; if ( not (success = Manipulator(segment2,_fsm).ripup(SegmentAction::OtherRipup)) ) continue; @@ -782,27 +791,27 @@ namespace Katana { for( TrackElement* segment3 : segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { DataNegociate* data3 = segment3->getDataNegociate(); - if ( not data3 ) continue; + if (not data3) continue; RoutingEvent* event3 = data3->getRoutingEvent(); - if ( not event3 ) continue; + if (not event3) continue; - if ( not toFree.intersect(event3->getConstraints()) ) { + if (not toFree.intersect(event3->getConstraints())) { cdebug_log(159,0) << " . " << segment3 << endl; continue; } cdebug_log(159,0) << " | " << segment3 << endl; - if ( shrinkRight xor shrinkLeft ) { - if ( shrinkRight ) { + if (shrinkRight xor shrinkLeft) { + if (shrinkRight) { if ( not (success=Manipulator(segment3,_fsm) .ripup( SegmentAction::OtherRipupPerpandAndPushAside , toFree.getVMin() - getPPitch()/2 )) ) break; - if ( event3->getTracksFree() == 1 ) { + if (event3->getTracksFree() == 1) { cdebug_log(159,0) << "Potential left intrication with other perpandicular." << endl; if ( segment3->getAxis() == segment2->getTargetAxis() ) { //leftIntrication = true; @@ -810,7 +819,7 @@ namespace Katana { } } } - if ( shrinkLeft ) { + if (shrinkLeft) { cdebug_log(159,0) << "Move PP to right: " << DbU::getValueString(toFree.getVMax()) << " + " << DbU::getValueString(getPPitch()/2) @@ -820,7 +829,7 @@ namespace Katana { , toFree.getVMax() + getPPitch()/2 )) ) break; - if ( event3->getTracksFree() == 1 ) { + if (event3->getTracksFree() == 1) { cdebug_log(159,0) << "Potential right intrication with other perpandicular." << endl; if ( segment3->getAxis() == segment2->getSourceAxis() ) { //rightIntrication = true; @@ -830,6 +839,7 @@ namespace Katana { } } else { if ( not (success=Manipulator(segment3,_fsm).ripup( SegmentAction::OtherRipup + | SegmentAction::DecreaseRipup | SegmentAction::EventLevel3 )) ) break; } @@ -856,7 +866,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis - , _fsm.getTrack(icost)->getAxis() ); + , _fsm.getCandidateAxis1(icost) ); } else _fsm.clearActions(); @@ -1057,7 +1067,7 @@ namespace Katana { _fsm.setState ( SegmentFsm::OtherRipup ); _fsm.addAction( _segment , SegmentAction::SelfInsert|SegmentAction::MoveToAxis - , _fsm.getTrack(itrack)->getAxis() + , _fsm.getCandidateAxis1(itrack) ); break; } @@ -1091,7 +1101,7 @@ namespace Katana { RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_segment->getLayer()); cdebug_tabw(159,1); - for( Track* track : Tracks_Range::get(plane,uside)) { + for ( Track* track : Tracks_Range::get(plane,uside)) { size_t begin; size_t end; @@ -1175,7 +1185,7 @@ namespace Katana { } else { if (_segment->getLength() < 20*getPitch()) { if (not (flags & AllowShortPivotUp)) return false; - if (not _segment->canPivotUp(1.0,kflags)) return false; + if (not _segment->canPivotUp(1.0,(kflags & ~Flags::IgnoreContacts))) return false; } if (not _segment->canMoveUp(0.5,kflags)) return false; } @@ -1299,6 +1309,7 @@ namespace Katana { if (_segment->isFixed()) return false; if (not _event->canMinimize()) return false; + if (_segment->isNonPref()) return true; DbU::Unit minSpan = DbU::Max; DbU::Unit maxSpan = DbU::Min; @@ -1307,7 +1318,7 @@ namespace Katana { if (_segment->base()->getAutoSource()->getAnchor()) { cdebug_log(159,0) << " | " << _segment->base()->getAutoSource() << endl; Interval constraints ( _segment->base()->getAutoSource()->getUConstraints - (perpandicularTo(_segment->getDirection())) ); + (_segment->getDirection()) ); cdebug_log(159,0) << " | Constraints: " << constraints << endl; minSpan = min( minSpan, constraints.getVMax() ); @@ -1318,7 +1329,7 @@ namespace Katana { if (_segment->base()->getAutoTarget()->getAnchor()) { cdebug_log(159,0) << " | " << _segment->base()->getAutoTarget() << endl; Interval constraints ( _segment->base()->getAutoTarget()->getUConstraints - (perpandicularTo(_segment->getDirection())) ); + (_segment->getDirection()) ); cdebug_log(159,0) << " | Constraints: " << constraints << endl; minSpan = min( minSpan, constraints.getVMax() ); @@ -1587,9 +1598,17 @@ namespace Katana { } - void Manipulator::repackPerpandiculars () + void Manipulator::repackPerpandiculars ( uint32_t flags ) { - cdebug_log(159,0) << "Manipulator::repackPerpandiculars()" << endl; + cdebug_log(159,1) << "Manipulator::repackPerpandiculars()" << endl; + + uint32_t parallelActionFlags = SegmentAction::SelfRipup|SegmentAction::EventLevel4; + uint32_t perpandicularActionFlags = SegmentAction::SelfRipupPerpand; + + if (flags & Manipulator::PerpandicularsFirst) { + parallelActionFlags &= ~SegmentAction::EventLevel4; + perpandicularActionFlags |= SegmentAction::EventLevel4; + } const vector& perpandiculars = _event->getPerpandiculars(); for ( size_t iperpand=0 ; iperpandgetDataNegociate(); if (perpandicular->isFixed ()) continue; - if (perpandicular->isGlobal()) continue; + //if (perpandicular->isGlobal()) continue; if (not data) continue; if (data->getState() >= DataNegociate::RepairFailed) continue; if (RoutingEvent::getStage() == RoutingEvent::Repair) { + if (_segment->getDataNegociate()->getState() < DataNegociate::Repair) + _segment->getDataNegociate()->resetRipupCount(); + data->setState( DataNegociate::Repair ); if (data->getStateCount() > 1) data->resetStateCount(); } - _fsm.addAction( perpandicular, SegmentAction::SelfRipupPerpand ); + + cdebug_log(159,0) << "Perpandicular ripup: " << perpandicular << endl; + _fsm.addAction( perpandicular, perpandicularActionFlags ); } - _fsm.addAction( _segment, SegmentAction::SelfRipup|SegmentAction::EventLevel4 ); + _fsm.addAction( _segment, parallelActionFlags ); + + cdebug_tabw(159,-1); } diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 24243551..4ee8a512 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -18,6 +18,7 @@ #include #include #include +#include "hurricane/Breakpoint.h" #include "hurricane/DebugSession.h" #include "hurricane/Warning.h" #include "hurricane/Bug.h" @@ -73,7 +74,10 @@ namespace { if (not intersect.contains(cost.getInterval())) intersect.intersection( cost.getInterval() ); else { - cost.setLonguestOverlap( intersect.getSize() ); + DbU::Unit beginOverlap = cost.getInterval().getVMin() - intersect.getVMin(); + DbU::Unit endOverlap = intersect.getVMax() - cost.getInterval().getVMax(); + + cost.setLonguestOverlap( std::min( beginOverlap, endOverlap ) ); cost.setGlobalEnclosed(); } @@ -85,6 +89,7 @@ namespace { cost.mergeDataState( data->getState() ); if (data->getState() >= DataNegociate::LocalVsGlobal) { cdebug_log(159,0) << "MaximumSlack/LocalVsGlobal for " << segment << endl; + cost.setAtRipupLimit(); } } @@ -110,6 +115,27 @@ namespace { cdebug_log(159,0) << "| Increment Delta: " << DbU::getValueString(intersect.getSize()) << endl; cost.incDelta( intersect.getSize() ); + + // if (segment->base()->getId() == 70433) { + // cdebug_log(159,0) << "| G:" << cost.isForGlobal() + // << " L:" << segment->isLocal() + // << " rpD:" << segment->base()->getRpDistance() + // << " state:" << data->getState() + // << " (Dogleg:" << DataNegociate::Dogleg + // << ") ripup:" << data->getRipupCount() + // << endl; + // } + + if ( cost.isForGlobal() + and segment->isLocal() + and (segment->base()->getRpDistance() < 2) + and (data->getState() >= DataNegociate::Dogleg) + //and (data->getRipupCount() > Session::getConfiguration()->getRipupLimit(Configuration::LocalRipupLimit) - 2) + ) { + cost.setInfinite(); + cdebug_log(159,0) << "Infinite cost from (RP access)" << segment << endl; + } + } @@ -183,6 +209,7 @@ namespace Katana { using std::left; using std::right; using std::setprecision; + using Hurricane::Breakpoint; using Hurricane::Warning; using Hurricane::Bug; using Hurricane::tab; @@ -317,6 +344,13 @@ namespace Katana { if (created) { cdebug_log(159,0) << "* " << trackSegment << endl; + if (trackSegment->isNonPref()) { + _segments.push_back( trackSegment ); + cdebug_log(159,0) << "Non-preferred diection, do not attempt to set on track." << endl; + cdebug_tabw(159,-1); + return trackSegment; + } + RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(autoSegment->getLayer()); Track* track = plane->getTrackByPosition ( autoSegment->getAxis() ); Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) ); @@ -347,7 +381,7 @@ namespace Katana { trackSegment->invalidate(); if (trackSegment->isFixed()) { - Session::addInsertEvent( trackSegment, track ); + Session::addInsertEvent( trackSegment, track, track->getAxis() ); } else { _segments.push_back( trackSegment ); } @@ -512,7 +546,7 @@ namespace Katana { ofprofile << setw(10) << right << count << " "; for ( size_t i=0 ; i<6 ; ++i ) { if (i == depth) - ofprofile << setw(10) << right << setprecision(2) << event->getPriority () << " "; + ofprofile << setw(10) << right << setprecision(2) << event->getPriority() << " "; else ofprofile << setw(10) << right << setprecision(2) << 0.0 << " "; } @@ -531,12 +565,16 @@ namespace Katana { } else { cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " + << event->getEventLevel() << ":" << event->getPriority() + << ":" << DbU::getValueString(event->getSegment()->getLength()) << "> " << event->getSegment() << endl; cmess2.flush(); } + //if (RoutingEvent::getProcesseds() == 14473) + // Breakpoint::stop( 0, "Before processing RoutingEvent 14473." ); + event->process( _eventQueue, _eventHistory, _eventLoop ); count++; @@ -630,6 +668,7 @@ namespace Katana { if (not (flags & Flags::PreRoutedStage)) { _katana->preProcess(); + _katana->_computeCagedConstraints(); Session::revalidate(); } diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index bb6a8b53..7c3fea1d 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -23,6 +23,7 @@ #include "hurricane/Technology.h" #include "hurricane/BasicLayer.h" #include "hurricane/RegularLayer.h" +#include "hurricane/Pad.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" #include "hurricane/RoutingPad.h" @@ -52,6 +53,7 @@ namespace { using Hurricane::Net; using Hurricane::DeepNet; using Hurricane::Horizontal; + using Hurricane::Pad; using Hurricane::Vertical; using Hurricane::RoutingPad; using Hurricane::NetExternalComponents; @@ -502,7 +504,8 @@ namespace { // - plane->getLayerGauge()->getHalfWireWidth() // - DbU::fromLambda(0.1); DbU::Unit delta = plane->getLayerGauge()->getObstacleDw() - DbU::fromLambda(0.1); - DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getLayer()->getMinimalSpacing()/2; + DbU::Unit extension = layer->getExtentionCap(); + //DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getLayer()->getMinimalSpacing()/2; //DbU::Unit extension = layer->getExtentionCap() - plane->getLayerGauge()->getHalfPitch() + getHalfWireWidth(); //DbU::Unit extension = layer->getExtentionCap(); //DbU::Unit extension = Session::getExtentionCap(); @@ -512,9 +515,9 @@ namespace { DbU::Unit axisMax = 0; cdebug_log(159,0) << " delta:" << DbU::getValueString(delta) - << " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch()) - << " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth()) - << ")" << endl; + << " (pitch:" << DbU::getValueString(plane->getLayerGauge()->getPitch()) + << " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth()) + << ")" << endl; // if ( type == Constant::PinOnly ) { // cdebug_log(159,0) << " Layer is PinOnly." << endl; @@ -540,7 +543,7 @@ namespace { } cdebug_log(159,0) << " chunk: [" << DbU::getValueString((*ichunk).getVMin()) - << ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl; + << ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl; segment = Horizontal::create ( net , layer @@ -1076,6 +1079,19 @@ namespace { << " " << basicLayer << endl; _powerRailsPlanes.merge ( bb, rootNet ); + } else { + const Pad* pad = dynamic_cast(component); + if (pad != NULL) { + _goMatchCount++; + + Box bb = pad->getBoundingBox( basicLayer ); + transformation.applyOn( bb ); + + cdebug_log(159,0) << " Merging PowerRail element: " << pad << " bb:" << bb + << " " << basicLayer << endl; + + _powerRailsPlanes.merge( bb, rootNet ); + } } } } diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index 4c230688..cb20ae50 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -120,9 +120,9 @@ namespace { void propagateCagedConstraints ( TrackElement* segment, set& faileds ) { - if (not segment->isFixed()) return; + cdebug_log(159,0) << "propagateCagedConstraints(): " << segment << endl; - cdebug_log(159,0) << "Propagate caging: " << segment << endl; + if (not segment->isFixed()) return; Track* track = segment->getTrack(); //Flags direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer()); @@ -208,7 +208,6 @@ namespace { Interval constraints ( minConstraint, maxConstraint ); for ( size_t iperpand=0 ; iperpandbase()->mergeUserConstraints( constraints ); if (perpandiculars[iperpand]->base()->getUserConstraints().isEmpty()) { cdebug_log(159,0) << "Cumulative caged constraints are too tight on " << perpandiculars[iperpand] << endl; @@ -257,7 +256,7 @@ namespace { Configuration* configuration = Session::getConfiguration(); const Layer* metal2 = configuration->getRoutingLayer( 1 ); - const Layer* metal3 = configuration->getRoutingLayer( 2 ); + //const Layer* metal3 = configuration->getRoutingLayer( 2 ); Net* neighborNet = NULL; RoutingPlane* metal3plane = track->getRoutingPlane()->getTop(); @@ -282,12 +281,6 @@ namespace { if ( (segment->getSourceU() - freeInterval.getVMin() < ppitch*3) or (freeInterval.getVMax() - segment->getTargetU() < ppitch*3) ) { cparanoid << "[INFO] Caged terminal: " << segment << endl; - if ( (segment->getLayer () != metal2) - or (segment->getLength() >= ppitch) - or (segment->getNet () == neighborNet) ) { - neighborNet = segment->getNet(); - continue; - } Anabatic::AutoContact* support = NULL; Anabatic::AutoContact* turn = NULL; @@ -299,6 +292,19 @@ namespace { turn = segment->base()->getAutoSource(); } + DbU::Unit supportLength = support->getConstraintBox().getWidth(); + cdebug_log(159,0) << "Support length (rp): " << DbU::getValueString(supportLength) << endl; + + if ( (segment->getLayer () != metal2) + //or (segment->getLength() >= ppitch) + or (supportLength >= ppitch) + or (segment->getNet () == neighborNet) ) { + neighborNet = segment->getNet(); + continue; + } + + cdebug_log(159,0) << "Protect " << segment << endl; + RoutingPad* rp = dynamic_cast(support->getAnchor()); Track* metal3track = metal3plane->getTrackByPosition( rp->getSourcePosition().getX() ); @@ -321,6 +327,7 @@ namespace { } lastMovedUp = segment->getSourceU(); +#if NOT_NEEDED_AFTER_6502_OPTIM Anabatic::AutoContact* source = Anabatic::AutoContactTerminal::create( support->getGCell() , rp @@ -342,6 +349,7 @@ namespace { AutoSegment* fixedSegment = AutoSegment::create( source, target, Flags::Vertical ); fixedSegment->setFlags( AutoSegment::SegFixed ); Session::getNegociateWindow()->createTrackSegment( fixedSegment, Flags::LoadingStage ); +#endif } neighborNet = segment->getNet(); @@ -415,7 +423,6 @@ namespace Katana { } //DebugSession::close(); - Session::revalidate (); } diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 05f4980f..8adae5ec 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -99,9 +99,17 @@ namespace Katana { if ( (lhs._segFlags & AutoSegment::SegFixedAxis) and not (rhs._segFlags & AutoSegment::SegFixedAxis)) return false; if (not (lhs._segFlags & AutoSegment::SegFixedAxis) and (rhs._segFlags & AutoSegment::SegFixedAxis)) return true; + if (lhs._rpDistance > rhs._rpDistance) return true; + if (lhs._rpDistance < rhs._rpDistance) return false; + if (lhs._layerDepth > rhs._layerDepth) return true; if (lhs._layerDepth < rhs._layerDepth) return false; + if (lhs._rpDistance == 0) { + if (lhs._length > rhs._length) return true; + if (lhs._length < rhs._length) return false; + } + if (lhs._priority > rhs._priority) return false; if (lhs._priority < rhs._priority) return true; @@ -126,6 +134,7 @@ namespace Katana { RoutingEvent::Key::Key ( const RoutingEvent* event ) : _tracksNb (event->getTracksNb()) + , _rpDistance (event->getSegment()->base()->getRpDistance()) , _priority (event->getPriority()) , _eventLevel (event->getEventLevel()) , _segFlags (event->getSegment()->base()->getFlags()) @@ -143,6 +152,7 @@ namespace Katana { if (not event) return; _tracksNb = event->getTracksNb(); + _rpDistance = event->getSegment()->base()->getRpDistance(); _priority = event->getPriority(); _eventLevel = event->getEventLevel(); _segFlags = event->getSegment()->base()->getFlags(); @@ -358,6 +368,8 @@ namespace Katana { if (getStage() == Repair) { fork->setMode( RoutingEvent::Repair ); + if (_segment->getDataNegociate()->getState() < DataNegociate::Repair) + _segment->getDataNegociate()->resetRipupCount(); _segment->getDataNegociate()->setState( DataNegociate::Repair ); } else if (getStage() == RoutingEvent::Pack) { fork->setMode( RoutingEvent::Pack ); @@ -587,10 +599,11 @@ namespace Katana { if (fsm.getState() == SegmentFsm::EmptyTrackList) return; if (fsm.isSymmetric()) return; - cdebug_tabw(159,1); - for ( size_t i = 0 ; i < fsm.getCosts().size() ; i++ ) - cdebug_log(159,0) << "| " << fsm.getCost(i) << endl; - cdebug_tabw(159,-1); + + cdebug_log(159,0) << "| Candidate Tracks:" << endl; + size_t itrack = 0; + for ( itrack = 0 ; itrack < fsm.getCosts().size() ; itrack++ ) + cdebug_log(159,0) << "| " << itrack << ":" << fsm.getCost(itrack) << endl; if (fsm.getCosts().size() and fsm.getCost(0)->isFree()) { cdebug_log(159,0) << "Insert in free space." << endl; @@ -602,8 +615,10 @@ namespace Katana { cdebug_log(159,0) << "| " << perpandicular << endl; fsm.addAction( perpandicular, SegmentAction::SelfInsert ); DataNegociate* data = perpandicular->getDataNegociate(); - if (data and (data->getState() < DataNegociate::Repair)) + if (data and (data->getState() < DataNegociate::Repair)) { data->setState( DataNegociate::Repair ); + data->resetRipupCount(); + } } } fsm.doActions(); @@ -611,16 +626,18 @@ namespace Katana { } else { switch ( fsm.getData()->getStateCount() ) { case 1: - // First try: minimize. - Manipulator(_segment,fsm).minimize(); - fsm.addAction( _segment, SegmentAction::SelfInsert ); + // First try: minimize or replace perpandiculars first. + if (Manipulator(_segment,fsm).minimize()) + fsm.addAction( _segment, SegmentAction::SelfInsert ); + else + Manipulator(_segment,fsm).repackPerpandiculars( Manipulator::PerpandicularsFirst ); fsm.doActions(); queue.commit(); break; case 2: // Second try: failed re-inserted first. - Manipulator(_segment,fsm).repackPerpandiculars(); - fsm.addAction( _segment, SegmentAction::SelfInsert ); + Manipulator(_segment,fsm).repackPerpandiculars( 0 ); + //fsm.addAction( _segment, SegmentAction::SelfInsert ); fsm.doActions(); queue.commit(); break; @@ -635,6 +652,8 @@ namespace Katana { void RoutingEvent::revalidate () { + if (_segment->isNonPref()) { _revalidateNonPref(); return; } + DebugSession::open( _segment->getNet(), 156, 160 ); cdebug_log(159,1) << "RoutingEvent::revalidate() - " << this << endl; @@ -719,6 +738,66 @@ namespace Katana { } + void RoutingEvent::_revalidateNonPref () + { + DebugSession::open( _segment->getNet(), 156, 160 ); + + cdebug_log(159,1) << "RoutingEvent::_revalidateNonPref() - " << this << endl; + + setAxisHintFromParent(); + cdebug_log(159,0) << "axisHint:" << DbU::getValueString(getAxisHint()) << endl; + + _overConstrained = false; + _segment->base()->getConstraints( _constraints ); + _segment->base()->getOptimal ( _optimal ); + + cdebug_log(159,0) << "Stage:" << RoutingEvent::getStage() << endl; + cdebug_log(159,0) << "| Raw Track Constraint: " << _constraints + << " [" << _constraints.getVMin() + << "," << _constraints.getVMax() << "]" << endl; + + _tracksNb = 0; + + Interval perpandicular = _constraints; + perpandicular.intersection( getPerpandicularFree() ); + cdebug_log(159,0) << "| Perpandicular Free: " << perpandicular << endl; + + size_t depth = Session::getRoutingGauge()->getLayerDepth( _segment->getLayer() ); + + depth += (depth+1 <= Session::getConfiguration()->getAllowedDepth()) ? 1 : -1; + RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByIndex( depth ); + + if (not perpandicular.isEmpty()) { + Track* track = plane->getTrackByPosition( perpandicular.getVMin() ); + + if ( track and (track->getAxis() < perpandicular.getVMin()) ) track = track->getNextTrack(); + for ( ; track and (track->getAxis() <= perpandicular.getVMax()) + ; track = track->getNextTrack(), _tracksNb++ ); + } + if (not _tracksNb) { + cdebug_log(159,0) << "| Reverting to pure constraints." << endl; + Track* track = plane->getTrackByPosition( _constraints.getVMin() ); + + if ( track && (track->getAxis() < _constraints.getVMin()) ) track = track->getNextTrack(); + for ( ; track && (track->getAxis() <= _constraints.getVMax()) + ; track = track->getNextTrack(), _tracksNb++ ); + } + if (not _tracksNb) { + cdebug_log(159,0) << "| Pure constraints are too tight." << endl; + if (_segment->base()) + _overConstrained = _segment->base()->getAutoSource()->isTerminal() + and _segment->base()->getAutoTarget()->isTerminal(); + } + + _segment->computePriority(); + + cdebug_log(159,0) << _segment << " has " << (int)_tracksNb << " choices " << perpandicular << endl; + cdebug_tabw(159,-1); + + DebugSession::close(); + } + + string RoutingEvent::_getTypeName () const { return "RoutingEvent"; } diff --git a/katana/src/RoutingPlane.cpp b/katana/src/RoutingPlane.cpp index ef6d702a..fd18f9a8 100644 --- a/katana/src/RoutingPlane.cpp +++ b/katana/src/RoutingPlane.cpp @@ -95,9 +95,7 @@ namespace Katana { if (not plane->_layerGauge) throw Error( badLayerGauge, depth, getString(katana->getConfiguration()->getRoutingGauge()).c_str() ); - DbU::Unit hExtension = 0; - DbU::Unit vExtension = 0; - uint32_t gaugeDepth = 0; + uint32_t gaugeDepth = 0; if (Session::getLayerGauge(gaugeDepth)->getType() == Constant::PinOnly) ++gaugeDepth; DbU::Unit extensionCap = ( std::max( Session::getWireWidth(depth), Session::getViaWidth(depth) ) diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index ca785832..e4ddcde6 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -366,19 +366,26 @@ namespace Katana { DebugSession::open( _segment->getNet(), 156, 160 ); if (_type & Lock) { - cdebug_log(159,0) << "* Lock // " << _segment << endl; + cdebug_log(159,1) << "* Lock // " << _segment << endl; } else if (_type & Perpandicular) { - cdebug_log(159,0) << "* Riping Pp " << _segment << endl; + cdebug_log(159,1) << "* Riping Pp " << _segment << endl; + } else if (_type & OtherRipup) { + cdebug_log(159,1) << "* Riping Other " << _segment << endl; } else { - cdebug_log(159,0) << "* Riping // " << _segment << endl; + cdebug_log(159,1) << "* Riping // " << _segment << endl; } if (_segment->isFixed()) { DebugSession::close(); return true; } DataNegociate* data = _segment->getDataNegociate(); - if (data == NULL) { DebugSession::close(); return true; } + if (data == NULL) { + cdebug_tabw(159,-1); + DebugSession::close(); + return true; + } - if (_type & ResetRipup) data->resetRipupCount(); + if (_type & ResetRipup ) data->resetRipupCount(); + if (_type & DecreaseRipup) data->decRipupCount (); if (_type & ToState) { data->setState ( _toState ); @@ -433,6 +440,7 @@ namespace Katana { fork->setMode( mode ); } + cdebug_tabw(159,-1); DebugSession::close(); return true; } @@ -547,29 +555,54 @@ namespace Katana { // _constraint.inflate ( 0, DbU::lambda(1.0) ); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment1->getLayer()); - for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) { - Track* track2 = NULL; - if (_event2) { - track2 = - (_sameAxis) ? track1 : plane->getTrackByPosition - ( segment2->getSymmetricAxis( symData->getSymmetrical( track1->getAxis() ) ) ); - cdebug_log(155,0) << "refTrack:" << track1 << endl; - cdebug_log(155,0) << "symTrack:" << track2 << endl; - cdebug_log(155,0) << "by symData: " << DbU::getValueString( symData->getSymmetrical(track1->getAxis()) ) << endl; - cdebug_log(155,0) << "plus segment2:" << DbU::getValueString( segment2->getSymmetricAxis(symData->getSymmetrical(track1->getAxis())) ) << endl; + if (segment1->isNonPref()) { + Track* baseTrack = plane->getTrackByPosition( segment1->base()->getSourcePosition(), Constant::Superior ); + + RoutingPlane* perpPlane = plane->getTop(); + if (not perpPlane) perpPlane = plane->getBottom(); + + for ( Track* ptrack : Tracks_Range::get(perpPlane,_constraint) ) { + _costs.push_back( new TrackCost(segment1,NULL,baseTrack,NULL,ptrack->getAxis(),0) ); + + cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getRefCandidateAxis()) + << " sum:" << DbU::getValueString(_costs.back()->getAxisWeight()) + << endl; + + if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) ) + _fullBlocked = false; + + cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << ptrack << endl; } - _costs.push_back( new TrackCost(segment1,segment2,track1,track2) ); + } else { + for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) { + Track* track2 = NULL; + DbU::Unit symAxis = 0; + if (_event2) { + track2 = + (_sameAxis) ? track1 : plane->getTrackByPosition + ( segment2->getSymmetricAxis( symData->getSymmetrical( track1->getAxis() ) ) ); + + if (track2) symAxis = track2->getAxis(); + + cdebug_log(155,0) << "refTrack:" << track1 << endl; + cdebug_log(155,0) << "symTrack:" << track2 << endl; + cdebug_log(155,0) << "by symData: " << DbU::getValueString( symData->getSymmetrical(track1->getAxis()) ) << endl; + cdebug_log(155,0) << "plus segment2:" << DbU::getValueString( segment2->getSymmetricAxis(symData->getSymmetrical(track1->getAxis())) ) << endl; + } + + _costs.push_back( new TrackCost(segment1,segment2,track1,track2,track1->getAxis(),symAxis) ); - cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getTrack()->getAxis()) - << " sum:" << DbU::getValueString(_costs.back()->getAxisWeight()) - << endl; + cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getRefCandidateAxis()) + << " sum:" << DbU::getValueString(_costs.back()->getAxisWeight()) + << endl; + + if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) ) + _fullBlocked = false; - if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) ) - _fullBlocked = false; - - cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track1 << endl; + cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track1 << endl; + } } cdebug_tabw(159,-1); @@ -675,6 +708,7 @@ namespace Katana { } _actions.clear (); + cdebug_tabw(159,-1); } @@ -731,7 +765,7 @@ namespace Katana { _event1->setEventLevel( 0 ); cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; - Session::addInsertEvent( getSegment1(), getTrack1(i) ); + Session::addInsertEvent( getSegment1(), getTrack1(i), getCandidateAxis1(i) ); if (_event2) { _event2->resetInsertState(); @@ -740,7 +774,7 @@ namespace Katana { _event2->setProcessed( true ); cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; - Session::addInsertEvent( getSegment2(), getTrack2(i) ); + Session::addInsertEvent( getSegment2(), getTrack2(i), getCandidateAxis2(i) ); } setState( SegmentFsm::SelfInserted ); @@ -751,11 +785,11 @@ namespace Katana { { cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl; - Session::addMoveEvent( getSegment1(), getTrack1(i) ); + Session::addMoveEvent( getSegment1(), getTrack1(i), getCandidateAxis1(i) ); if (_event2) { cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl; - Session::addMoveEvent( getSegment2(), getTrack2(i) ); + Session::addMoveEvent( getSegment2(), getTrack2(i), getCandidateAxis2(i) ); } setState( SegmentFsm::SelfInserted ); @@ -848,13 +882,15 @@ namespace Katana { } else { cdebug_log(159,0) << "No disloggers found @" << DbU::getValueString(segment->getAxis()) << endl; - Interval freeSpan = Session::getKatanaEngine()-> - getTrackByPosition(segment->getLayer(),segment->getAxis())-> - getFreeInterval(segment->getSourceU(),segment->getNet()); + Track* track = Session::getKatanaEngine()->getTrackByPosition( segment->getLayer() + , segment->getAxis () ); + if (track) { + Interval freeSpan = track->getFreeInterval( segment->getSourceU(), segment->getNet() ); - if (freeSpan.contains(segment->getCanonicalInterval())) { - cdebug_log(159,0) << "Disloggers vanished, Segment can be re-inserted." << endl; - success = true; + if (freeSpan.contains(segment->getCanonicalInterval())) { + cdebug_log(159,0) << "Disloggers vanished, Segment can be re-inserted." << endl; + success = true; + } } } @@ -979,14 +1015,14 @@ namespace Katana { if (Session::getConfiguration()->isVH() and (segment->getDepth() == 1)) { if (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) { - cerr << "Break using ShortDogleg." << endl; + //cerr << "Break using ShortDogleg." << endl; success = true; break; } } else { if (other->isGlobal()) { cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl; - if ((success = Manipulator(other,*this).moveUp())) break; + if ((success = Manipulator(other,*this).moveUp(Manipulator::IgnoreContacts))) break; } cdebug_log(159,0) << "conflictSolveByPlaceds() - Relaxing self" << endl; @@ -1065,7 +1101,7 @@ namespace Katana { success = Manipulator(segment,*this).moveUp (Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp); } - } else { + } else if (not _costs.empty()) { Interval overlap = segment->getCanonicalInterval(); size_t begin; size_t end; @@ -1172,12 +1208,16 @@ namespace Katana { if (success) break; case DataNegociate::Minimize: if (data->getStateCount() >= 2) { - nextState = DataNegociate::MaximumSlack; + nextState = DataNegociate::Slacken; } success = manipulator.minimize(); if (success) break; case DataNegociate::Dogleg: case DataNegociate::Slacken: + if ((success = manipulator.slacken(Flags::HalfSlacken))) { + nextState = DataNegociate::MaximumSlack; + break; + } case DataNegociate::ConflictSolveByHistory: case DataNegociate::ConflictSolveByPlaceds: case DataNegociate::MoveUp: @@ -1231,11 +1271,11 @@ namespace Katana { if (success) break; } case DataNegociate::Dogleg: - if (nextState == DataNegociate::Dogleg) { - nextState = DataNegociate::Slacken; - success = manipulator.makeDogleg(); + if (nextState == DataNegociate::Dogleg) { + nextState = DataNegociate::Slacken; + success = manipulator.makeDogleg(); + } if (success) break; - } case DataNegociate::Slacken: if (nextState == DataNegociate::Slacken) { nextState = DataNegociate::ConflictSolveByPlaceds; @@ -1324,7 +1364,7 @@ namespace Katana { cdebug_log(159,0) << "Global, SegmentFsm: Slacken " << ((manipulator.getEvent()) ? manipulator.getEvent()->getConstraints() : "(no event yet)") << endl; - if ( manipulator.getEvent() + if ( manipulator.getEvent() and manipulator.getEvent()->getConstraints().isPonctual() and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) { moveUpFlags |= Manipulator::AllowTerminalMoveUp; @@ -1435,9 +1475,10 @@ namespace Katana { _data2->resetRipupCount(); } - if (segment1->isStrap()) { success = _slackenStrap ( segment1, _data1, flags ); } - else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); } - else { success = _slackenGlobal( segment1, _data1, flags ); } + if ( segment1->isStrap() + or segment1->isUnbreakable()) { success = _slackenStrap ( segment1, _data1, flags ); } + else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); } + else { success = _slackenGlobal( segment1, _data1, flags ); } if (success) { actionFlags |= SegmentAction::ResetRipup; @@ -1445,6 +1486,9 @@ namespace Katana { actionFlags &= ~SegmentAction::EventLevel5; actionFlags |= SegmentAction::EventLevel3; } + if (segment1->isNonPref()) { + actionFlags &= ~SegmentAction::AllEventLevels; + } addAction( segment1, actionFlags ); } else { clearActions(); diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index 37cf0ec5..d975efd7 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -97,9 +97,10 @@ namespace Katana { Session::Session ( KatanaEngine* katana ) : Super(katana) - , _insertEvents() - , _removeEvents() - , _sortEvents () + , _indirectInvalids() + , _insertEvents () + , _removeEvents () + , _sortEvents () { } @@ -206,18 +207,25 @@ namespace Katana { } - void Session::_doRemovalEvents () + void Session::_doRemovalEvents ( bool reschedule ) { + cdebug_log(159,1) << "Katana::Session::_doRemovalEvents()" << endl; + set packTracks; for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) { + cdebug_log(159,0) << "Event:" << _removeEvents[i]._segment << endl; + if (not _removeEvents[i]._segment->getTrack()) continue; _removeEvents[i]._segment->detach( packTracks ); + if (reschedule) _removeEvents[i]._segment->reschedule( 0 ); } _removeEvents.clear(); for ( set::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it ) (*it)->doRemoval(); + + cdebug_tabw(159,-1); } @@ -236,18 +244,26 @@ namespace Katana { size_t Session::_revalidate () { cdebug_log(159,1) << "Katana::Session::_revalidate()" << endl; + uint32_t overlaps = 0; + + //Track* checkTrack = NULL; + //if (getKatanaEngine()->getRoutingPlaneByIndex( 1 )) + // checkTrack = getKatanaEngine()->getRoutingPlaneByIndex( 1 )->getTrackByIndex( 87 ); _doLockEvents(); _doRemovalEvents(); + //if (checkTrack) checkTrack->check( overlaps, "Session::_revalidate() - check track 82 @270." ); for ( const Event& event : _insertEvents ) { if (event._segment) { - if (event._segment->isReduced()) event._segment->setAxis( event._track->getAxis() ); - else event._track->insert( event._segment ); + if (event._segment->getAxis() != event._axis) event._segment->setAxis( event._axis ); + if (not event._segment->isReduced()) event._track->insert( event._segment ); } if (event._marker) event._track->insert( event._marker ); } _insertEvents.clear(); + _doRemovalEvents( false ); + //if (checkTrack) checkTrack->check( overlaps, "Session::_revalidate() - check track 82 @270." ); // Check if to be destroyeds are not associateds with TrackSegments. const set& destroyeds = getDestroyeds(); @@ -279,11 +295,11 @@ namespace Katana { } _doglegReset(); -# if defined(CHECK_DATABASE) - uint32_t overlaps = 0; -# endif for ( Track* track : _sortEvents ) { track->doReorder(); + if (cdebug.enabled()) { + track->check( overlaps, "Session::_revalidate() - track sorting." ); + } # if defined(CHECK_DATABASE) track->check( overlaps, "Session::_revalidate() - track sorting." ); # endif @@ -316,6 +332,22 @@ namespace Katana { } } + // for ( TrackElement* trackSegment : _indirectInvalids ) { + // cdebug_log(159,0) << "Indirect reschedule:" << trackSegment << endl; + // trackSegment->reschedule( 0 ); + // // addRemoveEvent( trackSegment ); + + // // if (trackSegment->getDataNegociate() and trackSegment->getDataNegociate()->hasRoutingEvent()) { + // // RoutingEvent* event = trackSegment->getDataNegociate()->getRoutingEvent(); + // // if ( not event->isDisabled() + // // and not event->isUnimplemented() + // // and event->isProcessed()) { + // // trackSegment->reschedule( 0 ); + // // } + // // } + // } + _indirectInvalids.clear(); + _doRemovalEvents(); for ( Track* track : _sortEvents ) track->doReorder(); _sortEvents.clear(); @@ -353,10 +385,11 @@ namespace Katana { } - void Session::_addInsertEvent ( TrackElement* segment, Track* track ) + void Session::_addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis ) { cdebug_log(159,0) << "addInsertEvent() " << segment - << "\n @" << track << endl; + << "\n @" << DbU::getValueString(axis) + << " " << track << endl; if ( segment->getTrack() != NULL ) { cerr << Bug("Session::addInsertEvent(): Segment already in Track." @@ -368,7 +401,7 @@ namespace Katana { return; } - _insertEvents.push_back( Event(segment,track) ); + _insertEvents.push_back( Event(segment,track,axis) ); _addSortEvent( track, true ); } @@ -382,7 +415,7 @@ namespace Katana { } cdebug_log(159,0) << "Ripup: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl; - _removeEvents.push_back( Event(segment,segment->getTrack()) ); + _removeEvents.push_back( Event(segment,segment->getTrack(),segment->getAxis()) ); _addSortEvent( segment->getTrack(), true ); } @@ -396,11 +429,11 @@ namespace Katana { } cdebug_log(159,0) << "Lock: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl; - _lockEvents.push_back( Event(segment,NULL) ); + _lockEvents.push_back( Event(segment,NULL,0) ); } - void Session::_addMoveEvent ( TrackElement* segment, Track* track ) + void Session::_addMoveEvent ( TrackElement* segment, Track* track, DbU::Unit axis ) { if (not segment->getTrack()) { cerr << Bug( " Katana::Session::addMoveEvent() : %s is not yet in a track." @@ -409,7 +442,7 @@ namespace Katana { _addRemoveEvent( segment ); } - _addInsertEvent( segment, track ); + _addInsertEvent( segment, track, axis ); } diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 56ba691b..1cb809a6 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -93,11 +93,14 @@ namespace Katana { { cdebug_log(155,1) << "Track::_preDestroy() - " << (void*)this << " " << this << endl; + set dummy; for ( size_t i=0 ; i<_segments.size() ; i++ ) if (_segments[i]) { - _segments[i]->detach(); - if (not _segments[i]->getTrackCount()) + _segments[i]->detach( dummy ); + if (not _segments[i]->getTrackCount()) { + //cerr << "destroy " << _segments[i] << endl; _segments[i]->destroy(); + } } for ( size_t i=0 ; i<_markers.size() ; i++ ) @@ -412,7 +415,8 @@ namespace Katana { Interval Track::expandFreeInterval ( size_t& begin, size_t& end, uint32_t state, Net* net ) const { - cdebug_log(155,1) << "Track::expandFreeInterval() begin:" << begin << " end:" << end << " " << net << endl; + cdebug_log(155,1) << "Track::expandFreeInterval() begin:" << begin << " end:" << end + << " state:" << state << " " << net << endl; cdebug_log(155,0) << _segments[begin] << endl; DbU::Unit minFree = _min; @@ -433,6 +437,11 @@ namespace Katana { if (_segments[end]->getNet() == net) { getNext( end, net ); + if (end != npos) { + cdebug_log(155,0) << "| same net, end:" << end << " " << _segments[end] << endl; + } else { + cdebug_log(155,0) << "| same net, end:" << end << " (after last)" << endl; + } if (end == npos) { end = _segments.size() - 1; @@ -440,7 +449,11 @@ namespace Katana { } else { setMaximalFlags( state, EndIsSegmentMin ); } + } else { + state = EndIsTrackMax; + cdebug_log(155,0) << "| already after last" << endl; } + cdebug_log(155,0) << "end:" << end << " state:" << state << endl; } @@ -474,14 +487,15 @@ namespace Katana { ,getString(segment).c_str()) << endl; } + cdebug_log(159,0) << "Insert in [" << 0 << "] " << this << segment << endl; _segments.push_back( segment ); _segmentsValid = false; - if (segment->isWide()) { - cdebug_log(155,0) << "Segment is wide." << endl; + if (segment->isWide() or segment->isNonPref()) { + cdebug_log(155,0) << "Segment is wide or non-pref, trackSpan:" << segment->getTrackSpan() << endl; Track* wtrack = getNextTrack(); for ( size_t i=1 ; wtrack and (igetTrackSpan()) ; ++i ) { - cdebug_log(155,0) << "Insert in [" << i << "] " << wtrack << endl; + cdebug_log(159,0) << "Insert in [" << i << "] " << wtrack << segment << endl; wtrack->_segments.push_back ( segment ); wtrack->_segmentsValid = false; wtrack = wtrack->getNextTrack(); @@ -508,13 +522,21 @@ namespace Katana { if (message) cerr << " o Checking Track - " << message << endl; cdebug_log(155,0) << (void*)this << ":" << this << endl; - for ( size_t i=0 ; i<_segments.size() ; i++ ) { - Interval trackRange ( _segments[i]->getAxis() - (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 - , _segments[i]->getAxis() + (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 ); - bool inTrackRange = trackRange.contains( _axis ); - if (_segments[i]) { + bool inTrackRange = false; + + if (_segments[i]->isNonPref()) { + DbU::Unit min = 0; + DbU::Unit max = 0; + _segments[i]->base()->getCanonical( min, max ); + inTrackRange = Interval(min,max).contains( _axis ); + } else { + Interval trackRange ( _segments[i]->getAxis() - (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 + , _segments[i]->getAxis() + (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 ); + inTrackRange = trackRange.contains( _axis ); + } + if (i) { if (_segments[i-1] == _segments[i]) { cerr << "[CHECK] incoherency at " << i << " " @@ -598,7 +620,7 @@ namespace Katana { case EndIsTrackMax: return _max; case EndIsSegmentMin: return _segments[index ]->getSourceU (); case EndIsNextSegmentMin: if (index+1 >= getSize()) return _max; - return _segments[index+1]->getSourceU (); + return _segments[index+1]->getSourceU (); case EndIsSegmentMax: return _segments[index ]->getTargetU (); } @@ -655,7 +677,7 @@ namespace Katana { Interval mergedInterval; _segments[seed]->getCanonical( mergedInterval ); - cdebug_log(155,0) << "| seed:" << _segments[seed] << endl; + cdebug_log(155,0) << "| seed:" << mergedInterval << " " << _segments[seed] << endl; size_t i = seed; while ( --i != npos ) { @@ -663,7 +685,7 @@ namespace Katana { _segments[i]->getCanonical ( segmentInterval ); if (segmentInterval.getVMax() >= mergedInterval.getVMin()) { - cdebug_log(155,0) << "| merge (prev):" << _segments[i] << endl; + cdebug_log(155,0) << "| merge (prev):" << segmentInterval << " " << _segments[i] << endl; mergedInterval.merge( segmentInterval ); begin = i; @@ -748,10 +770,12 @@ namespace Katana { if ( (j<_segments.size()) && (_segments[i]->getTargetU() > _segments[j]->getSourceU()) ) { - cerr << Error("Overlap in %s between:\n %s\n %s" + cerr << Error("Overlap in %s between:\n %s\n %s\n TargetU:%s SourceU:%s" ,getString(this).c_str() ,getString(_segments[i]).c_str() - ,getString(_segments[j]).c_str()) << endl; + ,getString(_segments[j]).c_str() + ,DbU::getValueString(_segments[i]->getTargetU()).c_str() + ,DbU::getValueString(_segments[j]->getSourceU()).c_str() ) << endl; overlaps++; } } @@ -763,7 +787,8 @@ namespace Katana { string Track::_getString () const { return "<" + _getTypeName() + " " - + getString(getLayer()) + " @" + + "[" + getString(_index) + "] " + + getString(getLayer()->getName()) + " @" + DbU::getValueString(_axis) + " [" + DbU::getValueString(_min) + ":" + DbU::getValueString(_max) + "] [" diff --git a/katana/src/TrackCost.cpp b/katana/src/TrackCost.cpp index af1c484f..f3e4613d 100644 --- a/katana/src/TrackCost.cpp +++ b/katana/src/TrackCost.cpp @@ -37,27 +37,45 @@ namespace Katana { , TrackElement* symSegment , Track* refTrack , Track* symTrack + , DbU::Unit refCandidateAxis + , DbU::Unit symCandidateAxis ) - : _flags ((symSegment) ? Symmetric : NoFlags) - , _span (refSegment->getTrackSpan()) - , _tracks ( _span * ((symSegment) ? 2 : 1) - , std::tuple(NULL,Track::npos,Track::npos) ) - , _segment1 (refSegment) - , _segment2 (symSegment) - , _interval1 (refSegment->getCanonicalInterval()) - , _interval2 ((symSegment) ? symSegment->getCanonicalInterval() : Interval()) - , _terminals (0) - , _delta (-_interval1.getSize() -_interval2.getSize()) - , _deltaShared (0) - , _deltaPerpand (0) - , _axisWeight (0) - , _distanceToFixed(2*Session::getSliceHeight()) - , _longuestOverlap(0) - , _dataState (0) - , _ripupCount (0) - , _selectFlags (NoFlags) - , _selectIndex (0) + : _flags ((symSegment) ? Symmetric : NoFlags) + , _span (refSegment->getTrackSpan()) + , _refCandidateAxis(refCandidateAxis) + , _symCandidateAxis(refCandidateAxis) + , _tracks ( _span * ((symSegment) ? 2 : 1) + , std::tuple(NULL,Track::npos,Track::npos) ) + , _segment1 (refSegment) + , _segment2 (symSegment) + , _interval1 (refSegment->getCanonicalInterval()) + , _interval2 ((symSegment) ? symSegment->getCanonicalInterval() : Interval()) + , _terminals (0) + , _delta (-_interval1.getSize() -_interval2.getSize()) + , _deltaShared (0) + , _deltaPerpand (0) + , _axisWeight (0) + , _distanceToFixed (2*Session::getSliceHeight()) + , _longuestOverlap (0) + , _dataState (0) + , _ripupCount (0) + , _selectFlags (NoFlags) + , _selectIndex (0) { + if (refSegment->isNonPref()) { + DbU::Unit axisShift = getRefCandidateAxis() - refSegment->getAxis(); + _interval1.translate( axisShift ); + + if (symSegment) { + throw Error( "TrackCost::TrackCost(): Symmetric management is not implemented for Non-preferred routing segments.\n" + " %s", getString(refSegment).c_str() ); + } + } + if (not _span) { + throw Error( "TrackCost::TrackCost(): Zero track span is not allowed.\n" + " %s", getString(refSegment).c_str() ); + } + cdebug_log(159,1) << "TrackCost::TrackCost() - " << refSegment << endl; cdebug_log(159,0) << " interval1: " << _interval1 << endl; @@ -87,7 +105,8 @@ namespace Katana { bool TrackCost::Compare::operator() ( const TrackCost* lhs, const TrackCost* rhs ) { - if ( lhs->isInfinite() xor rhs->isInfinite() ) return rhs->isInfinite(); + if ( lhs->isInfinite () xor rhs->isInfinite () ) return rhs->isInfinite(); + if ( lhs->isAtRipupLimit() xor rhs->isAtRipupLimit() ) return rhs->isAtRipupLimit(); if ( (_flags & TrackCost::DiscardGlobals) and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) ) @@ -160,8 +179,8 @@ namespace Katana { } - Net* TrackCost::getNet1 () const { return (_segment1) ? _segment1->getNet() : NULL; } - Net* TrackCost::getNet2 () const { return (_segment2) ? _segment2->getNet() : NULL; } + Net* TrackCost::getNet1 () const { return (_segment1) ? _segment1->getNet() : NULL; } + Net* TrackCost::getNet2 () const { return (_segment2) ? _segment2->getNet() : NULL; } size_t TrackCost::getBegin ( size_t i, uint32_t flags ) const @@ -232,7 +251,8 @@ namespace Katana { { string s = "<" + _getTypeName(); - s += " " + getString(getTrack(0)); + s += " @" + DbU::getValueString(getRefCandidateAxis()); + s += " " + getString(getTrack(0)->getLayer()->getName()); s += " " + getString(_dataState); s += "+" + getString(_ripupCount); s += ":" + getString((_dataState<<2)+_ripupCount); @@ -243,6 +263,7 @@ namespace Katana { s += string ( (isOverlap() )?"o":"-" ); s += string ( (isOverlapGlobal() )?"g":"-" ); s += string ( (isGlobalEnclosed())?"e":"-" ); + s += string ( (isAtRipupLimit ())?"R":"-" ); s += string ( (isAnalog ())?"a":"-" ); s += string ( (isShortNet ())?"N":"-" ); s += " " + getString(_terminals); diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 5e1abb58..9968db8a 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -141,6 +141,7 @@ namespace Katana { bool TrackElement::isDrag () const { return false; } bool TrackElement::isStrongTerminal ( Flags ) const { return false; } bool TrackElement::isStrap () const { return false; } + bool TrackElement::isUnbreakable () const { return false; } bool TrackElement::isSlackened () const { return false; } bool TrackElement::isDogleg () const { return false; } bool TrackElement::isShortDogleg () const { return false; } @@ -149,6 +150,7 @@ namespace Katana { bool TrackElement::isUserDefined () const { return false; } bool TrackElement::isAnalog () const { return false; } bool TrackElement::isWide () const { return false; } + bool TrackElement::isNonPref () const { return false; } bool TrackElement::isShortNet () const { return false; } // Predicates. bool TrackElement::hasSymmetric () const { return false; } @@ -175,7 +177,6 @@ namespace Katana { DataNegociate* TrackElement::getDataNegociate ( Flags ) const { return NULL; } TrackElements TrackElement::getPerpandiculars () { return new TrackElements_Perpandiculars(NULL); } void TrackElement::invalidate () { } - TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; } TrackElement* TrackElement::getSourceDogleg () { return NULL; } TrackElement* TrackElement::getTargetDogleg () { return NULL; } TrackElement* TrackElement::getSymmetric () { return NULL; } @@ -187,10 +188,11 @@ namespace Katana { void TrackElement::setDoglegLevel ( uint32_t ) { } void TrackElement::swapTrack ( TrackElement* ) { } void TrackElement::reschedule ( uint32_t ) { } - void TrackElement::detach () { } +//void TrackElement::detach () { } void TrackElement::detach ( set& ) { } void TrackElement::revalidate () { } void TrackElement::updatePPitch () { } + void TrackElement::updateTrackSpan () { } void TrackElement::setAxis ( DbU::Unit, uint32_t flags ) { } TrackElement* TrackElement::makeDogleg () { return NULL; } Flags TrackElement::makeDogleg ( Interval, TrackElement*&, TrackElement*&, Flags ) { return Flags::NoFlags; } diff --git a/katana/src/TrackFixedSegment.cpp b/katana/src/TrackFixedSegment.cpp index 9f0fd70f..38823e22 100644 --- a/katana/src/TrackFixedSegment.cpp +++ b/katana/src/TrackFixedSegment.cpp @@ -74,16 +74,24 @@ namespace Katana { const Layer* layer1 = track->getLayer()->getBlockageLayer(); RegularLayer* layer2 = dynamic_cast(technology->getLayer(layer1->getMask())); if ( layer2 ) { - Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() ); - Interval segside; + //cerr << track->getLayer() << " minSpace:" << DbU::getValueString(track->getLayer()->getMinimalSpacing()) << endl; + + Interval segside; + Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() ); + DbU::Unit cap = track->getLayer()->getMinimalSpacing()/2 /*+ track->getLayer()->getExtentionCap()*/; if (track->getDirection() == Flags::Horizontal) { segside = Interval( boundingBox.getXMin(), boundingBox.getXMax() ); - _sourceU = max( boundingBox.getXMin(), uside.getVMin()); - _targetU = min( boundingBox.getXMax(), uside.getVMax()); + _sourceU = max( boundingBox.getXMin() - cap, uside.getVMin()); + _targetU = min( boundingBox.getXMax() + cap, uside.getVMax()); } else { segside = Interval( boundingBox.getYMin(), boundingBox.getYMax() ); - _sourceU = max( boundingBox.getYMin(), uside.getVMin()); - _targetU = min( boundingBox.getYMax(), uside.getVMax()); + _sourceU = max( boundingBox.getYMin() - cap, uside.getVMin()); + _targetU = min( boundingBox.getYMax() + cap, uside.getVMax()); + } + + Flags gcellFlags = Flags::NoFlags; + if (segment->getNet()->isSupply() and (depth > 0)) { + gcellFlags |= Flags::GoStraight; } GCellsUnder gcells = track->getKatanaEngine()->getGCellsUnder( segment ); @@ -91,6 +99,7 @@ namespace Katana { GCell* gcell = gcells->gcellAt(i); gcell->addBlockage ( depth, gcell->getSide( track->getDirection() ).getIntersection( segside ).getSize() ); + gcell->flags() |= gcellFlags; } } } @@ -124,7 +133,7 @@ namespace Katana { cdebug_log(159,0) << "Adding: " << segment << " on " << track << endl; cdebug_log(159,0) << "TrackFixedSegment::create(): " << trackFixedSegment << endl; - Session::addInsertEvent( trackFixedSegment, track ); + Session::addInsertEvent( trackFixedSegment, track, track->getAxis() ); } return trackFixedSegment; } @@ -132,7 +141,7 @@ namespace Katana { AutoSegment* TrackFixedSegment::base () const { return NULL; } Segment* TrackFixedSegment::getSegment () const { return _segment; } - DbU::Unit TrackFixedSegment::getAxis () const { return getTrack()->getAxis(); } + DbU::Unit TrackFixedSegment::getAxis () const { return getTrack() ? getTrack()->getAxis() : 0; } bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); } bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); } bool TrackFixedSegment::isFixed () const { return true; } diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 88b06591..f18d3811 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -17,6 +17,7 @@ #include #include #include "hurricane/Bug.h" +#include "hurricane/DebugSession.h" #include "hurricane/Warning.h" #include "hurricane/BasicLayer.h" #include "hurricane/Net.h" @@ -28,6 +29,7 @@ #include "katana/DataNegociate.h" #include "katana/RoutingPlane.h" #include "katana/TrackSegmentRegular.h" +#include "katana/TrackSegmentNonPref.h" #include "katana/TrackSegmentWide.h" #include "katana/Track.h" #include "katana/Session.h" @@ -42,6 +44,7 @@ namespace Katana { using Hurricane::tab; using Hurricane::ForEachIterator; using Hurricane::Bug; + using Hurricane::DebugSession; using Hurricane::Error; using Hurricane::BasicLayer; using Hurricane::Net; @@ -129,22 +132,36 @@ namespace Katana { TrackElement* TrackSegment::create ( AutoSegment* segment, Track* track, bool& created ) { + DebugSession::open( segment->getNet(), 159, 160 ); + created = false; + bool useNonPref = (segment->getDirection() xor Session::getDirection(segment->getLayer())); + DbU::Unit defaultWireWidth = Session::getWireWidth( segment->base()->getLayer() ); TrackElement* trackElement = Session::lookup( segment->base() ); if (not trackElement) { - if (segment->base()->getWidth() <= defaultWireWidth) - trackElement = new TrackSegmentRegular( segment, track ); - else - trackElement = new TrackSegmentWide ( segment, track ); + if (useNonPref) { + trackElement = new TrackSegmentNonPref( segment ); + if (track) + cerr << Error( "TrackSegment::create(): Must not set track when creating a non-preferred element.\n" + " (on %s)", getString(segment).c_str() ) << endl; + } else { + if (segment->base()->getWidth() <= defaultWireWidth) + trackElement = new TrackSegmentRegular( segment, track ); + else + trackElement = new TrackSegmentWide ( segment, track ); + } trackElement->_postCreate(); trackElement->invalidate(); created = true; - cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl; + cdebug_log(159,0) << "TrackSegment::create(): " << "nonPref:" <isVertical(); } bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); } bool TrackSegment::isGlobal () const { return _base->isWeakGlobal() or _base->isGlobal(); } + bool TrackSegment::isUnbreakable () const { return _base->isUnbreakable(); } bool TrackSegment::isBipoint () const { return _base->isBipoint(); } bool TrackSegment::isTerminal () const { return _base->isTerminal(); } bool TrackSegment::isDrag () const { return _base->isDrag(); } @@ -192,7 +210,6 @@ namespace Katana { uint32_t TrackSegment::getDoglegLevel () const { return _dogLegLevel; } Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); } Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); } - TrackElement* TrackSegment::getCanonical ( Interval& i ) { return Session::lookup( _base->getCanonical(i)->base() ); } TrackElement* TrackSegment::getSymmetric () { return _symmetric; } TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); } // Mutators. @@ -389,13 +406,20 @@ namespace Katana { { if (track) { DbU::Unit axis = track->getAxis(); - if (getTrackSpan() > 1) { + if (isWide()) { DbU::Unit pitch = track->getRoutingPlane()->getLayerGauge()->getPitch(); axis += (pitch * (getTrackSpan() - 1)) / 2; - + cdebug_log(155,0) << "TrackSegment::setTrack(): pitch:" << DbU::getValueString(pitch) << " trackSpan:" << getTrackSpan() << endl; } + if (isNonPref()) { + axis = getAxis(); + + cdebug_log(155,0) << "TrackSegment::setTrack(): Non-preferred, keep @" << DbU::getValueString(axis) + << " trackSpan:" << getTrackSpan() << endl; + } + addTrackCount( getTrackSpan() ); setAxis( axis, AutoSegment::SegAxisSet ); } @@ -407,28 +431,36 @@ namespace Katana { { _symmetric = dynamic_cast( segment ); } - void TrackSegment::detach () - { - cdebug_log(159,0) << "TrackSegment::detach() - " << endl; + // void TrackSegment::detach () + // { + // cdebug_log(159,0) << "TrackSegment::detach() - " << endl; - setTrack( NULL ); - setFlags( TElemLocked ); - addTrackCount( -1 ); - } + // setTrack( NULL ); + // setFlags( TElemLocked ); + // addTrackCount( -1 ); + // } void TrackSegment::detach ( set& removeds ) { - cdebug_log(159,0) << "TrackSegment::detach(set&) - " << endl; + cdebug_log(159,1) << "TrackSegment::detach(set&) - trackSpan:" + << getTrackSpan() << endl; Track* wtrack = getTrack(); for ( size_t i=0 ; wtrack and (igetNextTrack(); } + //addTrackCount( -getTrackSpan() ); + addTrackCount( -1 ); - detach(); + //detach(); + setTrack( NULL ); + setFlags( TElemLocked ); + + cdebug_tabw(159,-1); } @@ -437,9 +469,25 @@ namespace Katana { unsetFlags( TElemCreated ); cdebug_log(159,0) << "revalidate() - " << this << endl; - _base->getCanonical( _sourceU, _targetU ); + if (isNonPref()) { + Interval perpandicularSpan ( getAxis() ); + perpandicularSpan.inflate( base()->getExtensionCap( Anabatic::Flags::Source ) ); - if (_track) Session::addSortEvent( _track, true ); + _sourceU = perpandicularSpan.getVMin(); + _targetU = perpandicularSpan.getVMax(); + } + else + _base->getCanonical( _sourceU, _targetU ); + + if (isNonPref()) updateTrackSpan(); + + if (_track) { + Track* wtrack = getTrack(); + for ( size_t i=0 ; wtrack and (igetNextTrack(); + } + } unsetFlags( TElemInvalidated ); } @@ -782,6 +830,23 @@ namespace Katana { cdebug_log(159,0) << "Source: " << *gcells.begin () << endl; cdebug_log(159,0) << "Target: " << *gcells.rbegin() << endl; + AutoContact* acSource = base()->getAutoSource(); + AutoContact* acTarget = base()->getAutoTarget(); + if (gcells[0] == doglegGCell) { + if (acSource->isHDogleg() or acSource->isVDogleg()) { + cdebug_log(159,0) << "false: Source perpandicular already has a dogleg." << endl; + cdebug_tabw(159,-1); + return false; + } + } + if (gcells[gcells.size()-1] == doglegGCell) { + if (acTarget->isHDogleg() or acTarget->isVDogleg()) { + cdebug_log(159,0) << "false: Target perpandicular already has a dogleg." << endl; + cdebug_tabw(159,-1); + return false; + } + } + bool isGCellInside = false; for ( size_t igcell=0 ; igcellcheckPositions(); - base()->getCanonical( min, max ); + + if (isNonPref()) { + Interval perpandicularSpan ( getAxis() ); + perpandicularSpan.inflate( base()->getExtensionCap( Anabatic::Flags::Source ) ); + + min = perpandicularSpan.getVMin(); + max = perpandicularSpan.getVMax(); + } + else + _base->getCanonical( min, max ); + if (getSourceU() != min) { cerr << "[CHECK] " << this << " has bad source position " << "cache:" << DbU::getValueString(getSourceU()) << " vs. " diff --git a/katana/src/TrackSegmentNonPref.cpp b/katana/src/TrackSegmentNonPref.cpp new file mode 100644 index 00000000..13fc27b5 --- /dev/null +++ b/katana/src/TrackSegmentNonPref.cpp @@ -0,0 +1,178 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./TrackSegmentNonPref.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/DebugSession.h" +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "hurricane/RoutingPad.h" +#include "anabatic/AutoContact.h" +#include "anabatic/GCell.h" +#include "crlcore/RoutingGauge.h" +#include "katana/DataNegociate.h" +#include "katana/TrackSegmentNonPref.h" +#include "katana/Track.h" +#include "katana/RoutingPlane.h" +#include "katana/Session.h" +#include "katana/RoutingEvent.h" +#include "katana/NegociateWindow.h" +#include "katana/KatanaEngine.h" + + +namespace Katana { + + using namespace std; + using Hurricane::tab; + using Hurricane::DebugSession; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::BasicLayer; + using Hurricane::Net; + using Hurricane::Name; + using Hurricane::RoutingPad; + using Anabatic::AutoSegment; + using Anabatic::perpandicularTo; + + +// ------------------------------------------------------------------- +// Class : "TrackSegmentNonPref". + + + TrackSegmentNonPref::TrackSegmentNonPref ( AutoSegment* segment ) + : Super(segment,NULL) + , _trackSpan (0) + , _trackCount(0) + { + cdebug_log(159,1) << "CTOR TrackSegmentNonPref " << (void*)this << ":" << this << endl; + cdebug_log(159,0) << " over " << (void*)segment << ":" << segment << endl; + + updateTrackSpan(); + + cdebug_tabw(159,-1); + } + + + void TrackSegmentNonPref::_postCreate () + { + Super::_postCreate(); + } + + + TrackSegmentNonPref::~TrackSegmentNonPref () + { + } + + + void TrackSegmentNonPref::_preDestroy () + { + Super::_preDestroy(); + } + + + bool TrackSegmentNonPref::isNonPref () const { return true; } + size_t TrackSegmentNonPref::getTrackSpan () const { return _trackSpan; } + uint32_t TrackSegmentNonPref::getTrackCount () const { return _trackCount; } + + + void TrackSegmentNonPref::updateTrackSpan () + { + DebugSession::open( getNet(), 150, 160 ); + cdebug_log(159,1) << "TrackSegmentNonPref::updateTrackspan() " << (void*)this << ":" << this << endl; + + RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_base->getLayer()); + Interval newAxisSpan ( _base->getSourcePosition(), _base->getTargetPosition() ); + Track* ntrack = plane->getTrackByPosition( newAxisSpan.getVMin(), Constant::Superior ); + + cdebug_log(159,0) << "new Axis span: " << newAxisSpan << endl; + + if (ntrack) { + cdebug_log(159,0) << "+ " << ntrack << endl; + _trackSpan = 0; + for ( ; ntrack and newAxisSpan.contains(ntrack->getAxis()) + ; ntrack = ntrack->getNextTrack(), _trackSpan++ ) { + cdebug_log(159,0) << "| " << ntrack << endl; + } + } + if (not _trackSpan) _trackSpan = 1; + cdebug_log(159,0) << "_trackSpan: " << _trackSpan << endl; + + cdebug_tabw(159,-1); + DebugSession::close(); + } + + + void TrackSegmentNonPref::addTrackCount ( int32_t count ) + { + if (count > 0) _trackCount += count; + else { + if (-count > (int32_t)_trackCount) _trackCount = 0; + _trackCount -= -count; + } + } + + + void TrackSegmentNonPref::addOverlapCost ( TrackCost& cost ) const + { + uint32_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()); + bool inLocalDepth = (depth < 3); + Track* track = cost.getTrack(); + + if (not track) return; + DbU::Unit axisCandidate = cost.getRefCandidateAxis(); + + cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 ); + cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 ); + cost.setDistanceToFixed(); + cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight( axisCandidate ) ); + cost.incDeltaPerpand( getDataNegociate()->getWiringDelta( axisCandidate ) ); + + cdebug_log(155,0) << "incAxisWeight:" << DbU::getValueString(axisCandidate) + << " of " << DbU::getValueString(getDataNegociate()->getRoutingEvent()->getAxisWeight( axisCandidate )) + << " (sum:" << DbU::getValueString(cost.getAxisWeight()) << ")" + << endl; + + for ( size_t span=0 ; (span < _trackSpan) and (track != NULL) ; ++span ) { + track->addOverlapCost( cost ); + // Todo: have to choose here wether we go *next* or *previous* according + // to the symmetry kind. + track = track->getNextTrack(); + cost.selectNextTrack(); + } + + if (isGlobal()) cost.setForGlobal(); + + if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) ) + cost.setInfinite(); + + cost.select( 0, TrackCost::NoFlags ); + } + + + void TrackSegmentNonPref::invalidate () + { + if (isInvalidated()) return; + + Super::invalidate(); + + if (getTrack()) reschedule( 0 ); + } + + +} // Katana namespace. diff --git a/katana/src/TrackSegmentRegular.cpp b/katana/src/TrackSegmentRegular.cpp index 4965cc66..504226b5 100644 --- a/katana/src/TrackSegmentRegular.cpp +++ b/katana/src/TrackSegmentRegular.cpp @@ -90,13 +90,13 @@ namespace Katana { cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 ); cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 ); + if (isGlobal()) cost.setForGlobal(); track->addOverlapCost( cost ); cost.setDistanceToFixed(); cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) ); cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) ); - if (isGlobal()) cost.setForGlobal(); if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) ) cost.setInfinite(); diff --git a/katana/src/Tracks.cpp b/katana/src/Tracks.cpp index 8773ebb8..fcd7e1b6 100644 --- a/katana/src/Tracks.cpp +++ b/katana/src/Tracks.cpp @@ -43,7 +43,8 @@ namespace Katana { _track = routingPlane->getTrackByPosition ( _constraints.getVMin() ); cdebug_log(155,0) << "* Nearest track: " << _track << endl;; - cdebug_log(155,0) << "* axis:" << _track->getAxis() << " vmin:" << _constraints.getVMin() << endl; + cdebug_log(155,0) << "* axis:" << ((_track) ? DbU::getValueString(_track->getAxis()) : string("None")) + << " vmin:" << _constraints.getVMin() << endl; if ( _track and (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNextTrack(); if ( _track and (_track->getAxis() > _constraints.getVMax()) ) _track = NULL; diff --git a/katana/src/katana/Manipulator.h b/katana/src/katana/Manipulator.h index 587851a9..a532e5c1 100644 --- a/katana/src/katana/Manipulator.h +++ b/katana/src/katana/Manipulator.h @@ -63,7 +63,7 @@ namespace Katana { bool isCaged ( DbU::Unit ) const; bool ripup ( uint32_t type, DbU::Unit axisHint=0 ); bool ripupPerpandiculars ( uint32_t flags=0 ); - void repackPerpandiculars (); + void repackPerpandiculars ( uint32_t flags ); void reprocessPerpandiculars (); bool ripple (); bool minimize (); diff --git a/katana/src/katana/RoutingEvent.h b/katana/src/katana/RoutingEvent.h index b54267ed..fe8f5e62 100644 --- a/katana/src/katana/RoutingEvent.h +++ b/katana/src/katana/RoutingEvent.h @@ -66,7 +66,8 @@ namespace Katana { Key ( const RoutingEvent* ); void update ( const RoutingEvent* ); private: - unsigned int _tracksNb:16; + unsigned int _tracksNb :16; + unsigned int _rpDistance: 4; float _priority; uint32_t _eventLevel; uint32_t _segFlags; @@ -135,6 +136,7 @@ namespace Katana { inline uint32_t getInsertState () const; inline uint32_t getEventLevel () const; void revalidate (); + void _revalidateNonPref (); inline void updateKey (); void process ( RoutingEventQueue& , RoutingEventHistory& diff --git a/katana/src/katana/RoutingPlane.h b/katana/src/katana/RoutingPlane.h index 88103168..7cda121b 100644 --- a/katana/src/katana/RoutingPlane.h +++ b/katana/src/katana/RoutingPlane.h @@ -67,7 +67,7 @@ namespace Katana { protected: // Attributes. - KatanaEngine* _katana; + KatanaEngine* _katana; RoutingLayerGauge* _layerGauge; size_t _depth; Flags _flags; diff --git a/katana/src/katana/SegmentFsm.h b/katana/src/katana/SegmentFsm.h index 20197e15..af6e6453 100644 --- a/katana/src/katana/SegmentFsm.h +++ b/katana/src/katana/SegmentFsm.h @@ -39,18 +39,20 @@ namespace Katana { , Insert = (1<< 3) , Ripup = (1<< 4) , RipedByLocal = (1<< 5) - , ResetRipup = (1<< 6) - , ToRipupLimit = (1<< 7) - , MoveToAxis = (1<< 8) - , AxisHint = (1<< 9) - , Lock = (1<<10) - , PackingMode = (1<<11) - , ToState = (1<<12) - , EventLevel1 = (1<<13) - , EventLevel2 = (1<<14) - , EventLevel3 = (1<<15) - , EventLevel4 = (1<<16) - , EventLevel5 = (1<<17) + , DecreaseRipup = (1<< 6) + , ResetRipup = (1<< 7) + , ToRipupLimit = (1<< 8) + , MoveToAxis = (1<< 9) + , AxisHint = (1<<10) + , Lock = (1<<11) + , PackingMode = (1<<12) + , ToState = (1<<13) + , EventLevel1 = (1<<14) + , EventLevel2 = (1<<15) + , EventLevel3 = (1<<16) + , EventLevel4 = (1<<17) + , EventLevel5 = (1<<18) + , AllEventLevels = EventLevel1|EventLevel2|EventLevel3|EventLevel4|EventLevel5 , SelfLock = Self |Lock , SelfInsert = Self |Insert , SelfRipup = Self |Ripup @@ -115,6 +117,7 @@ namespace Katana { inline bool isFullBlocked () const; inline bool isSymmetric () const; inline bool isMinimizeDrag () const; + inline bool hasAction ( TrackElement* ) const; inline RoutingEvent* getEvent () const; inline RoutingEvent* getEvent1 () const; inline RoutingEvent* getEvent2 () const; @@ -139,6 +142,8 @@ namespace Katana { inline size_t getEnd ( size_t icost, size_t itrack=0 ); inline size_t getEnd1 ( size_t icost, size_t itrack=0 ); inline size_t getEnd2 ( size_t icost, size_t itrack=0 ); + inline DbU::Unit getCandidateAxis1 ( size_t icost ) const; + inline DbU::Unit getCandidateAxis2 ( size_t icost ) const; inline vector& getActions (); inline void setState ( uint32_t ); void setDataState ( uint32_t ); @@ -192,39 +197,47 @@ namespace Katana { }; - inline bool SegmentFsm::isMinimizeDrag () const { return _minimizeDrag; } - inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } - inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } - inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } - inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } - inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } - inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } - inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } - inline uint32_t SegmentFsm::getState () const { return _state; } - inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } - inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } - inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } - inline DataNegociate* SegmentFsm::getData1 () { return _data1; } - inline DataNegociate* SegmentFsm::getData2 () { return _data2; } - inline Interval& SegmentFsm::getConstraint () { return _constraint; } - inline Interval& SegmentFsm::getOptimal () { return _optimal; } - inline vector& SegmentFsm::getCosts () { return _costs; } - inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; } - inline Track* SegmentFsm::getTrack ( size_t icost, size_t itrack ) { return (_useEvent2) ? getTrack2(icost,itrack) : getTrack1(icost,itrack); } - inline size_t SegmentFsm::getBegin ( size_t icost, size_t itrack ) { return (_useEvent2) ? getBegin2(icost,itrack) : getBegin1(icost,itrack); } - inline size_t SegmentFsm::getEnd ( size_t icost, size_t itrack ) { return (_useEvent2) ? getEnd2 (icost,itrack) : getEnd1 (icost,itrack); } - inline Track* SegmentFsm::getTrack1 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::NoFlags ); } - inline Track* SegmentFsm::getTrack2 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::Symmetric); } - inline size_t SegmentFsm::getBegin1 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::NoFlags ); } - inline size_t SegmentFsm::getBegin2 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::Symmetric); } - inline size_t SegmentFsm::getEnd1 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::NoFlags ); } - inline size_t SegmentFsm::getEnd2 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::Symmetric); } - inline vector& SegmentFsm::getActions () { return _actions; } - inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } - inline void SegmentFsm::clearActions () { _actions.clear(); } - inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; } - inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; } + inline bool SegmentFsm::isMinimizeDrag () const { return _minimizeDrag; } + inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } + inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } + inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } + inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } + inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } + inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } + inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } + inline uint32_t SegmentFsm::getState () const { return _state; } + inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } + inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } + inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } + inline DataNegociate* SegmentFsm::getData1 () { return _data1; } + inline DataNegociate* SegmentFsm::getData2 () { return _data2; } + inline Interval& SegmentFsm::getConstraint () { return _constraint; } + inline Interval& SegmentFsm::getOptimal () { return _optimal; } + inline vector& SegmentFsm::getCosts () { return _costs; } + inline TrackCost* SegmentFsm::getCost ( size_t icost ) { return _costs[icost]; } + inline Track* SegmentFsm::getTrack ( size_t icost, size_t itrack ) { return (_useEvent2) ? getTrack2(icost,itrack) : getTrack1(icost,itrack); } + inline size_t SegmentFsm::getBegin ( size_t icost, size_t itrack ) { return (_useEvent2) ? getBegin2(icost,itrack) : getBegin1(icost,itrack); } + inline size_t SegmentFsm::getEnd ( size_t icost, size_t itrack ) { return (_useEvent2) ? getEnd2 (icost,itrack) : getEnd1 (icost,itrack); } + inline Track* SegmentFsm::getTrack1 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::NoFlags ); } + inline Track* SegmentFsm::getTrack2 ( size_t icost, size_t itrack ) { return _costs[icost]->getTrack(itrack,TrackCost::Symmetric); } + inline size_t SegmentFsm::getBegin1 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::NoFlags ); } + inline size_t SegmentFsm::getBegin2 ( size_t icost, size_t itrack ) { return _costs[icost]->getBegin(itrack,TrackCost::Symmetric); } + inline size_t SegmentFsm::getEnd1 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::NoFlags ); } + inline size_t SegmentFsm::getEnd2 ( size_t icost, size_t itrack ) { return _costs[icost]->getEnd (itrack,TrackCost::Symmetric); } + inline DbU::Unit SegmentFsm::getCandidateAxis1 ( size_t icost ) const { return _costs[icost]->getRefCandidateAxis(); } + inline DbU::Unit SegmentFsm::getCandidateAxis2 ( size_t icost ) const { return _costs[icost]->getSymCandidateAxis(); } + inline vector& SegmentFsm::getActions () { return _actions; } + inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } + inline void SegmentFsm::clearActions () { _actions.clear(); } + inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; } + inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; } + inline bool SegmentFsm::hasAction ( TrackElement* segment ) const + { + for ( const SegmentAction& action : _actions ) + if (action.getSegment() == segment) return true; + return false; + } } // Katana namespace. diff --git a/katana/src/katana/Session.h b/katana/src/katana/Session.h index b92a3105..1f6d61cb 100644 --- a/katana/src/katana/Session.h +++ b/katana/src/katana/Session.h @@ -65,66 +65,74 @@ namespace Katana { public: typedef Anabatic::Session Super; public: - static Session* get ( const char* message=NULL ); - inline static Super* base (); - inline static bool isEmpty (); - inline static KatanaEngine* getKatanaEngine (); - static Configuration* getConfiguration (); - inline static Net* getBlockageNet (); - inline static NegociateWindow* getNegociateWindow (); - inline static uint32_t getRipupCost (); - inline static Anabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit ); - static void setInterrupt ( bool ); - inline static Interval& toAxisInterval ( Interval&, size_t depth ); - inline static void addInsertEvent ( TrackMarker* , Track* ); - inline static void addInsertEvent ( TrackElement* , Track* ); - inline static void addRemoveEvent ( TrackElement* ); - inline static void addMoveEvent ( TrackElement* , Track* ); - inline static void addSortEvent ( Track*, bool forced=false ); - inline static void addLockEvent ( TrackElement* ); - inline static size_t revalidate (); - static AutoContact* lookup ( Contact* ); - static TrackElement* lookup ( Segment* ); - static TrackElement* lookup ( AutoSegment* ); - static void addShortDogleg ( TrackElement*, TrackElement* ); - static TrackElement* getDoglegPaired ( TrackElement* ); - static Session* _open ( KatanaEngine* ); - private: - KatanaEngine* _getKatanaEngine (); - Net* _getBlockageNet (); - uint32_t _getRipupCost (); - Anabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit ); - Interval& _toAxisInterval ( Interval&, size_t depth ) const; - void _doLockEvents (); - void _doRemovalEvents (); - virtual size_t _revalidate (); - bool _isEmpty () const; - NegociateWindow* _getNegociateWindow (); - void _addInsertEvent ( TrackMarker* , Track* ); - void _addInsertEvent ( TrackElement* , Track* ); - void _addRemoveEvent ( TrackElement* ); - void _addMoveEvent ( TrackElement* , Track* ); - void _addSortEvent ( Track*, bool forced ); - void _addLockEvent ( TrackElement* ); - virtual Record* _getRecord () const; - virtual string _getTypeName () const; + static Session* get ( const char* message=NULL ); + inline static Super* base (); + inline static bool isEmpty (); + inline static KatanaEngine* getKatanaEngine (); + static Configuration* getConfiguration (); + inline static Net* getBlockageNet (); + inline static NegociateWindow* getNegociateWindow (); + inline static uint32_t getRipupCost (); + inline static Anabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit ); + inline static const std::vector& + getIndirectInvalids (); + static void setInterrupt ( bool ); + inline static Interval& toAxisInterval ( Interval&, size_t depth ); + inline static void addIndirectInvalid ( TrackElement* ); + inline static void addInsertEvent ( TrackMarker* , Track* ); + inline static void addInsertEvent ( TrackElement* , Track*, DbU::Unit axis ); + inline static void addRemoveEvent ( TrackElement* ); + inline static void addMoveEvent ( TrackElement* , Track*, DbU::Unit axis ); + inline static void addSortEvent ( Track*, bool forced=false ); + inline static void addLockEvent ( TrackElement* ); + inline static size_t revalidate (); + static AutoContact* lookup ( Contact* ); + static TrackElement* lookup ( Segment* ); + static TrackElement* lookup ( AutoSegment* ); + static void addShortDogleg ( TrackElement*, TrackElement* ); + static TrackElement* getDoglegPaired ( TrackElement* ); + static Session* _open ( KatanaEngine* ); + private: + KatanaEngine* _getKatanaEngine (); + Net* _getBlockageNet (); + uint32_t _getRipupCost (); + Anabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit ); + Interval& _toAxisInterval ( Interval&, size_t depth ) const; + void _doLockEvents (); + void _doRemovalEvents ( bool reschedule=false ); + virtual size_t _revalidate (); + bool _isEmpty () const; + NegociateWindow* _getNegociateWindow (); + inline const std::vector& + _getIndirectInvalids (); + inline void _addIndirectInvalid ( TrackElement* ); + void _addInsertEvent ( TrackMarker* , Track* ); + void _addInsertEvent ( TrackElement* , Track*, DbU::Unit axis ); + void _addRemoveEvent ( TrackElement* ); + void _addMoveEvent ( TrackElement* , Track*, DbU::Unit axis ); + void _addSortEvent ( Track*, bool forced ); + void _addLockEvent ( TrackElement* ); + virtual Record* _getRecord () const; + virtual string _getTypeName () const; protected: // Internal Classes. class Event { public: - inline Event ( TrackElement*, Track* ); + inline Event ( TrackElement*, Track*, DbU::Unit ); inline Event ( TrackMarker* , Track* ); public: TrackElement* _segment; TrackMarker* _marker; Track* _track; + DbU::Unit _axis; }; protected: // Attributes. - vector _insertEvents; - vector _removeEvents; - vector _lockEvents; - set _sortEvents; + vector _indirectInvalids; + vector _insertEvents; + vector _removeEvents; + vector _lockEvents; + set _sortEvents; protected: // Constructors & Destructors. Session ( KatanaEngine* ); @@ -138,16 +146,18 @@ namespace Katana { // Inline Functions. - inline Session::Event::Event ( TrackElement* segment , Track* track ) + inline Session::Event::Event ( TrackElement* segment , Track* track, DbU::Unit axis ) : _segment(segment) , _marker (NULL) , _track (track) + , _axis (axis) { } inline Session::Event::Event ( TrackMarker* marker , Track* track ) : _segment(NULL) , _marker (marker) , _track (track) + , _axis (0) { } @@ -169,20 +179,26 @@ namespace Katana { inline Anabatic::GCell* Session::getGCellUnder ( DbU::Unit x, DbU::Unit y ) { return get("getGCellUnder()")->_getGCellUnder(x,y); } + inline const std::vector& Session::getIndirectInvalids () + { return get("getIndirectInvalids()")->_getIndirectInvalids(); } + inline Interval& Session::toAxisInterval ( Interval& interval, size_t depth ) { return get("getGCellUnder()")->_toAxisInterval(interval,depth); } + inline void Session::addIndirectInvalid ( TrackElement* element ) + { get("addIndirectInvalid(TrackElement*)")->_addIndirectInvalid(element); } + inline void Session::addInsertEvent ( TrackMarker* marker, Track* track ) { get("addInsertEvent(TrackMarker*)")->_addInsertEvent(marker,track); } - inline void Session::addInsertEvent ( TrackElement* segment, Track* track ) - { get("addInsertEvent(TrackElement*)")->_addInsertEvent(segment,track); } + inline void Session::addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis ) + { get("addInsertEvent(TrackElement*)")->_addInsertEvent(segment,track,axis); } inline void Session::addRemoveEvent ( TrackElement* segment ) { get("addRemoveEvent()")->_addRemoveEvent(segment); } - inline void Session::addMoveEvent ( TrackElement* segment, Track* track ) - { get("addMoveEvent()")->_addMoveEvent(segment,track); } + inline void Session::addMoveEvent ( TrackElement* segment, Track* track, DbU::Unit axis ) + { get("addMoveEvent()")->_addMoveEvent(segment,track,axis); } inline void Session::addLockEvent ( TrackElement* segment ) { get("addLockEvent()")->_addLockEvent(segment); } @@ -196,6 +212,12 @@ namespace Katana { inline bool Session::isEmpty () { return get("isEmpty()")->_isEmpty(); } + inline const std::vector& Session::_getIndirectInvalids () + { return _indirectInvalids; } + + inline void Session::_addIndirectInvalid ( TrackElement* element ) + { _indirectInvalids.push_back( element ); } + } // Katana namespace. diff --git a/katana/src/katana/TrackCost.h b/katana/src/katana/TrackCost.h index 0bb90036..5af8ae29 100644 --- a/katana/src/katana/TrackCost.h +++ b/katana/src/katana/TrackCost.h @@ -60,9 +60,10 @@ namespace Katana { , RightOverlap = (1 << 15) , OverlapGlobal = (1 << 16) , GlobalEnclosed = (1 << 17) + , AtRipupLimit = (1 << 18) , MergeMask = ForGlobal |Blockage|Fixed |Infinite |HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal - |GlobalEnclosed + |GlobalEnclosed |AtRipupLimit }; public: @@ -80,85 +81,95 @@ namespace Katana { }; public: - TrackCost ( TrackElement* refSegment - , TrackElement* symSegment - , Track* refTrack - , Track* symTrack - ); - ~TrackCost (); - inline bool isForGlobal () const; - inline bool isBlockage () const; - inline bool isAnalog () const; - inline bool isShortNet () const; - inline bool isFixed () const; - inline bool isInfinite () const; - inline bool isOverlap () const; - inline bool isLeftOverlap () const; - inline bool isRightOverlap () const; - inline bool isHardOverlap () const; - inline bool isOverlapGlobal () const; - inline bool isGlobalEnclosed () const; - bool isFree () const; - inline bool isSymmetric () const; - inline bool isWide () const; - inline uint32_t getFlags () const; - inline size_t getSpan () const; - inline Net* getNet () const; - Net* getNet1 () const; - Net* getNet2 () const; - inline Track* getTrack () const; - inline size_t getBegin () const; - inline size_t getEnd () const; - inline Track* getTrack ( size_t i ) const; - inline size_t getBegin ( size_t i ) const; - inline size_t getEnd ( size_t i ) const; - inline Track* getTrack ( size_t i, uint32_t flags ) const; - size_t getBegin ( size_t i, uint32_t flags ) const; - size_t getEnd ( size_t i, uint32_t flags ) const; - inline const Interval& getInterval () const; - inline const Interval& getInterval1 () const; - inline const Interval& getInterval2 () const; - inline uint32_t getTerminals () const; - inline DbU::Unit getDelta () const; - inline DbU::Unit getDeltaPerpand () const; - inline DbU::Unit getLongestOverlap () const; - inline DbU::Unit getAxisWeight () const; - inline int getRipupCount () const; - inline uint32_t getDataState () const; - inline uint32_t setFlags ( uint32_t ); - inline void setTrack ( Track*, size_t begin, size_t end ); - inline void setForGlobal (); - inline void setBlockage (); - inline void setFixed (); - inline void setInfinite (); - inline void setOverlap (); - inline void setLeftOverlap (); - inline void setRightOverlap (); - inline void setHardOverlap (); - inline void setOverlapGlobal (); - inline void setGlobalEnclosed (); - inline void incTerminals ( uint32_t ); - inline void incDelta ( DbU::Unit ); - inline void incDeltaPerpand ( DbU::Unit ); - inline void incDeltaShared ( DbU::Unit ); - inline void incAxisWeight ( DbU::Unit ); - inline void setLonguestOverlap ( DbU::Unit ); - inline void mergeRipupCount ( int ); - inline void mergeDataState ( uint32_t ); - inline bool selectNextTrack (); - inline bool select ( size_t index, uint32_t flags ); - void consolidate (); - void setDistanceToFixed (); - Record* _getRecord () const; - string _getString () const; - inline string _getTypeName () const; - private: - TrackCost ( const TrackCost& ) = delete; - TrackCost& operator= ( const TrackCost& ) = delete; + TrackCost ( TrackElement* refSegment + , TrackElement* symSegment + , Track* refTrack + , Track* symTrack + , DbU::Unit refCandidateAxis + , DbU::Unit symCandidateAxis + ); + ~TrackCost (); + inline bool isForGlobal () const; + inline bool isBlockage () const; + inline bool isAnalog () const; + inline bool isShortNet () const; + inline bool isFixed () const; + inline bool isInfinite () const; + inline bool isOverlap () const; + inline bool isLeftOverlap () const; + inline bool isRightOverlap () const; + inline bool isHardOverlap () const; + inline bool isOverlapGlobal () const; + inline bool isGlobalEnclosed () const; + inline bool isAtRipupLimit () const; + bool isFree () const; + inline bool isSymmetric () const; + inline bool isWide () const; + inline uint32_t getFlags () const; + inline size_t getSpan () const; + inline Net* getNet () const; + Net* getNet1 () const; + Net* getNet2 () const; + inline TrackElement* getRefElement () const; + inline TrackElement* getSymElement () const; + inline DbU::Unit getRefCandidateAxis () const; + inline DbU::Unit getSymCandidateAxis () const; + inline Track* getTrack () const; + inline size_t getBegin () const; + inline size_t getEnd () const; + inline Track* getTrack ( size_t i ) const; + inline size_t getBegin ( size_t i ) const; + inline size_t getEnd ( size_t i ) const; + inline Track* getTrack ( size_t i, uint32_t flags ) const; + size_t getBegin ( size_t i, uint32_t flags ) const; + size_t getEnd ( size_t i, uint32_t flags ) const; + inline const Interval& getInterval () const; + inline const Interval& getInterval1 () const; + inline const Interval& getInterval2 () const; + inline uint32_t getTerminals () const; + inline DbU::Unit getDelta () const; + inline DbU::Unit getDeltaPerpand () const; + inline DbU::Unit getLongestOverlap () const; + inline DbU::Unit getAxisWeight () const; + inline int getRipupCount () const; + inline uint32_t getDataState () const; + inline uint32_t setFlags ( uint32_t ); + inline void setTrack ( Track*, size_t begin, size_t end ); + inline void setForGlobal (); + inline void setBlockage (); + inline void setFixed (); + inline void setInfinite (); + inline void setOverlap (); + inline void setLeftOverlap (); + inline void setRightOverlap (); + inline void setHardOverlap (); + inline void setOverlapGlobal (); + inline void setGlobalEnclosed (); + inline void setAtRipupLimit (); + inline void incTerminals ( uint32_t ); + inline void incDelta ( DbU::Unit ); + inline void incDeltaPerpand ( DbU::Unit ); + inline void incDeltaShared ( DbU::Unit ); + inline void incAxisWeight ( DbU::Unit ); + inline void setLonguestOverlap ( DbU::Unit ); + inline void mergeRipupCount ( int ); + inline void mergeDataState ( uint32_t ); + inline bool selectNextTrack (); + inline bool select ( size_t index, uint32_t flags ); + void consolidate (); + void setDistanceToFixed (); + Record* _getRecord () const; + string _getString () const; + inline string _getTypeName () const; + private: + TrackCost ( const TrackCost& ) = delete; + TrackCost& operator= ( const TrackCost& ) = delete; // Attributes. private: uint32_t _flags; size_t _span; + DbU::Unit _refCandidateAxis; + DbU::Unit _symCandidateAxis; std::vector< std::tuple > _tracks; TrackElement* _segment1; @@ -180,57 +191,63 @@ namespace Katana { // Inline Functions. - inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; } - inline bool TrackCost::isBlockage () const { return _flags & Blockage; } - inline bool TrackCost::isAnalog () const { return _flags & Analog; } - inline bool TrackCost::isShortNet () const { return _flags & ShortNet; } - inline bool TrackCost::isFixed () const { return _flags & Fixed; } - inline bool TrackCost::isInfinite () const { return _flags & Infinite; } - inline bool TrackCost::isOverlap () const { return _flags & Overlap; } - inline bool TrackCost::isLeftOverlap () const { return _flags & LeftOverlap; } - inline bool TrackCost::isRightOverlap () const { return _flags & RightOverlap; } - inline bool TrackCost::isHardOverlap () const { return _flags & HardOverlap; } - inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; } - inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; } - inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; } - inline bool TrackCost::isWide () const { return (_span > 1); } - inline uint32_t TrackCost::getFlags () const { return _flags; } - inline size_t TrackCost::getSpan () const { return _span; } - inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); } - inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); } - inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); } - inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); } - inline size_t TrackCost::getEnd () const { return getEnd (_selectIndex,_selectFlags); } - inline size_t TrackCost::getEnd ( size_t i ) const { return getEnd (i,NoFlags); } - inline const Interval& TrackCost::getInterval () const { return (_selectFlags & Symmetric) ? getInterval2() : getInterval1(); } - inline const Interval& TrackCost::getInterval1 () const { return _interval1; } - inline const Interval& TrackCost::getInterval2 () const { return _interval2; } - inline uint32_t TrackCost::getTerminals () const { return _terminals; } - inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; } - inline DbU::Unit TrackCost::getDelta () const { return _delta; } - inline DbU::Unit TrackCost::getAxisWeight () const { return _axisWeight; } - inline int TrackCost::getRipupCount () const { return _ripupCount; } - inline uint32_t TrackCost::getDataState () const { return _dataState; } - inline uint32_t TrackCost::setFlags ( uint32_t mask ) { _flags |= mask; return _flags; } - inline void TrackCost::setForGlobal () { _flags |= ForGlobal; } - inline void TrackCost::setBlockage () { _flags |= Blockage; } - inline void TrackCost::setFixed () { _flags |= Fixed; } - inline void TrackCost::setInfinite () { _flags |= Infinite; } - inline void TrackCost::setOverlap () { _flags |= Overlap; } - inline void TrackCost::setLeftOverlap () { _flags |= LeftOverlap; } - inline void TrackCost::setRightOverlap () { _flags |= RightOverlap; } - inline void TrackCost::setHardOverlap () { _flags |= HardOverlap; } - inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; } - inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; } - inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } - inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } - inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } - inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; } - inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; } - inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); } - inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); } - inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); } - inline string TrackCost::_getTypeName () const { return "TrackCost"; } + inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; } + inline bool TrackCost::isBlockage () const { return _flags & Blockage; } + inline bool TrackCost::isAnalog () const { return _flags & Analog; } + inline bool TrackCost::isShortNet () const { return _flags & ShortNet; } + inline bool TrackCost::isFixed () const { return _flags & Fixed; } + inline bool TrackCost::isInfinite () const { return _flags & Infinite; } + inline bool TrackCost::isOverlap () const { return _flags & Overlap; } + inline bool TrackCost::isLeftOverlap () const { return _flags & LeftOverlap; } + inline bool TrackCost::isRightOverlap () const { return _flags & RightOverlap; } + inline bool TrackCost::isHardOverlap () const { return _flags & HardOverlap; } + inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; } + inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; } + inline bool TrackCost::isAtRipupLimit () const { return _flags & AtRipupLimit; } + inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; } + inline bool TrackCost::isWide () const { return (_span > 1); } + inline uint32_t TrackCost::getFlags () const { return _flags; } + inline size_t TrackCost::getSpan () const { return _span; } + inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); } + inline TrackElement* TrackCost::getRefElement () const { return _segment1; } + inline TrackElement* TrackCost::getSymElement () const { return _segment2; } + inline DbU::Unit TrackCost::getRefCandidateAxis () const { return _refCandidateAxis; } + inline DbU::Unit TrackCost::getSymCandidateAxis () const { return _symCandidateAxis; } + inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); } + inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); } + inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); } + inline size_t TrackCost::getEnd () const { return getEnd (_selectIndex,_selectFlags); } + inline size_t TrackCost::getEnd ( size_t i ) const { return getEnd (i,NoFlags); } + inline const Interval& TrackCost::getInterval () const { return (_selectFlags & Symmetric) ? getInterval2() : getInterval1(); } + inline const Interval& TrackCost::getInterval1 () const { return _interval1; } + inline const Interval& TrackCost::getInterval2 () const { return _interval2; } + inline uint32_t TrackCost::getTerminals () const { return _terminals; } + inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; } + inline DbU::Unit TrackCost::getDelta () const { return _delta; } + inline DbU::Unit TrackCost::getAxisWeight () const { return _axisWeight; } + inline int TrackCost::getRipupCount () const { return _ripupCount; } + inline uint32_t TrackCost::getDataState () const { return _dataState; } + inline uint32_t TrackCost::setFlags ( uint32_t mask ) { _flags |= mask; return _flags; } + inline void TrackCost::setForGlobal () { _flags |= ForGlobal; } + inline void TrackCost::setBlockage () { _flags |= Blockage; } + inline void TrackCost::setFixed () { _flags |= Fixed; } + inline void TrackCost::setInfinite () { _flags |= Infinite; } + inline void TrackCost::setOverlap () { _flags |= Overlap; } + inline void TrackCost::setLeftOverlap () { _flags |= LeftOverlap; } + inline void TrackCost::setRightOverlap () { _flags |= RightOverlap; } + inline void TrackCost::setHardOverlap () { _flags |= HardOverlap; } + inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; } + inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; } + inline void TrackCost::setAtRipupLimit () { _flags |= AtRipupLimit; } + inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } + inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } + inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } + inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; } + inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; } + inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); } + inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); } + inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); } + inline string TrackCost::_getTypeName () const { return "TrackCost"; } inline TrackCost::Compare::Compare ( uint32_t flags ) : _flags(flags) { } @@ -238,8 +255,8 @@ namespace Katana { inline Track* TrackCost::getTrack () const { - cdebug_log( 55,0) << "TrackCost::getTrack() _index:" << _selectIndex - << " flags:" << _selectFlags << std::endl; + // cdebug_log( 55,0) << "TrackCost::getTrack() _index:" << _selectIndex + // << " flags:" << _selectFlags << std::endl; return getTrack(_selectIndex,_selectFlags); } @@ -278,9 +295,9 @@ namespace Katana { { if (i >= _span) return NULL; - cdebug_log( 55,0) << "TrackCost::getTrack() i:" << i - << " flags:" << flags - << " index:" << (i + ((flags & Symmetric) ? _span : 0)) << std::endl; + // cdebug_log( 55,0) << "TrackCost::getTrack() i:" << i + // << " flags:" << flags + // << " index:" << (i + ((flags & Symmetric) ? _span : 0)) << std::endl; return std::get<0>( _tracks[i + ((flags & Symmetric) ? _span : 0)] ); } diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index 93b29153..d5808031 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -66,8 +66,8 @@ namespace Katana { // Class : "TrackElement". enum TrackElementFlags { TElemCreated = (1 << 0) - , TElemBlockage = (1 << 1) - , TElemFixed = (1 << 2) + , TElemBlockage = (1 << 2) + , TElemFixed = (1 << 3) , TElemLocked = (1 << 4) , TElemRouted = (1 << 5) , TElemShortDogleg = (1 << 6) @@ -106,6 +106,8 @@ namespace Katana { virtual bool isHorizontal () const = 0; virtual bool isVertical () const = 0; virtual bool isWide () const; + virtual bool isNonPref () const; + virtual bool isUnbreakable () const; virtual bool isLocal () const; virtual bool isGlobal () const; virtual bool isBipoint () const; @@ -171,7 +173,7 @@ namespace Katana { virtual Interval getSourceConstraints () const; virtual Interval getTargetConstraints () const; virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const; - virtual TrackElement* getCanonical ( Interval& ); + inline TrackElement* getCanonical ( Interval& ); virtual size_t getGCells ( vector& ) const; virtual TrackElement* getParent () const; virtual uint32_t getDoglegLevel () const; @@ -194,11 +196,12 @@ namespace Katana { virtual void setDoglegLevel ( uint32_t ); virtual void swapTrack ( TrackElement* ); virtual void reschedule ( uint32_t level ); - virtual void detach (); + //virtual void detach (); virtual void detach ( std::set& ); virtual void invalidate (); virtual void revalidate (); virtual void updatePPitch (); + virtual void updateTrackSpan (); virtual void addTrackCount ( int32_t ); virtual void incOverlapCost ( TrackCost& ) const; virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::AutoSegment::SegAxisSet ); @@ -258,6 +261,7 @@ namespace Katana { inline DbU::Unit TrackElement::getLength () const { return getTargetU() - getSourceU(); } inline DbU::Unit TrackElement::getSourceU () const { return _sourceU; } inline DbU::Unit TrackElement::getTargetU () const { return _targetU; } + inline TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; } inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); } inline DbU::Unit TrackElement::getSymmetricAxis ( DbU::Unit axis ) const { return axis - (getTrackSpan()-1)*getPitch(); } diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index 9ad446ef..c799b208 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -73,6 +73,7 @@ namespace Katana { virtual bool isDrag () const; virtual bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; virtual bool isStrap () const; + virtual bool isUnbreakable () const; virtual bool isSlackened () const; virtual bool isDogleg () const; virtual bool isShortDogleg () const; @@ -115,7 +116,6 @@ namespace Katana { virtual Interval getSourceConstraints () const; virtual Interval getTargetConstraints () const; virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const; - virtual TrackElement* getCanonical ( Interval& ); virtual size_t getGCells ( vector& ) const; virtual TrackElement* getSourceDogleg (); virtual TrackElement* getTargetDogleg (); @@ -133,7 +133,7 @@ namespace Katana { virtual void setDoglegLevel ( uint32_t ); virtual void swapTrack ( TrackElement* ); virtual void reschedule ( uint32_t level ); - virtual void detach (); + //virtual void detach (); virtual void detach ( std::set& ); virtual void invalidate (); virtual void revalidate (); diff --git a/katana/src/katana/TrackSegmentNonPref.h b/katana/src/katana/TrackSegmentNonPref.h new file mode 100644 index 00000000..3313acd0 --- /dev/null +++ b/katana/src/katana/TrackSegmentNonPref.h @@ -0,0 +1,76 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Universite 2019-2019, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./katana/TrackSegmentNonPref.h" | +// +-----------------------------------------------------------------+ + + +#ifndef KATANA_TRACK_SEGMENT_NON_PREF_H +#define KATANA_TRACK_SEGMENT_NON_PREF_H + +#include +#include +#include "katana/TrackSegment.h" + + +namespace Katana { + + using std::string; + using std::map; + using std::set; + using std::binary_function; + using Hurricane::Record; + using Hurricane::Interval; + using Hurricane::DbU; + using Hurricane::Net; + using Hurricane::Layer; + using Anabatic::AutoSegment; + + class DataNegociate; + class Track; + class TrackCost; + + +// ------------------------------------------------------------------- +// Class : "TrackSegmentNonPref". + + class TrackSegmentNonPref : public TrackSegment { + friend class TrackSegment; + public: + typedef TrackSegment Super; + protected: + TrackSegmentNonPref ( AutoSegment* ) ; + virtual ~TrackSegmentNonPref (); + virtual void _postCreate (); + virtual void _preDestroy (); + virtual bool isNonPref () const; + virtual size_t getTrackSpan () const; + virtual uint32_t getTrackCount () const; + virtual void addOverlapCost ( TrackCost& ) const; + virtual void addTrackCount ( int32_t ); + virtual void updateTrackSpan (); + virtual void invalidate (); + private: + TrackSegmentNonPref ( const TrackSegmentNonPref& ) = delete; + TrackSegmentNonPref& operator= ( const TrackSegmentNonPref& ) = delete; + private: + size_t _trackSpan; + uint32_t _trackCount; + }; + + +} // Katana namespace. + + +INSPECTOR_P_SUPPORT(Katana::TrackSegmentNonPref); + +#endif // KATANA_TRACK_SEGMENT_WIDE_H diff --git a/knik/src/MatrixVertex.cpp b/knik/src/MatrixVertex.cpp index 2b9c4bc4..5e17a269 100644 --- a/knik/src/MatrixVertex.cpp +++ b/knik/src/MatrixVertex.cpp @@ -1,11 +1,10 @@ #include +#include "vlsisapd/configuration/Configuration.h" #include "hurricane/Cell.h" #include "hurricane/Box.h" - #include "crlcore/AllianceFramework.h" #include "crlcore/CellGauge.h" - #include "knik/Graph.h" #include "knik/MatrixVertex.h" #include "knik/KnikEngine.h" @@ -142,10 +141,13 @@ Vertex* MatrixVertex::createRegularMatrix () if ( _xInit || _yInit ) throw Error ("MatrixVertex::createRegularMatrix(): cannot initialize matrix twice."); + string gaugeName = Cfg::getParamString("katabatic.routingGauge","sxlib")->asString(); + Cell* cell = _routingGraph->getCell(); - DbU::Unit sliceHeight = AllianceFramework::get()->getCellGauge()->getSliceHeight(); - DbU::Unit cellWidth = cell->getAbutmentBox().getWidth(); - DbU::Unit cellHeight = cell->getAbutmentBox().getHeight(); + DbU::Unit sliceHeight = AllianceFramework::get()->getCellGauge(gaugeName)->getSliceHeight(); + DbU::Unit cellWidth = cell->getAbutmentBox().getWidth(); + DbU::Unit cellHeight = cell->getAbutmentBox().getHeight(); + _boundingBox = cell->getAbutmentBox(); _nbXTiles = (unsigned int)ceil(float(cellWidth) / float(sliceHeight)); _nbYTiles = (unsigned int)ceil(float(cellHeight) / float(sliceHeight));