diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index 59e864f7..0f3172ca 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -14,18 +14,19 @@ // +-----------------------------------------------------------------+ -#include -#include "hurricane/Bug.h" -#include "hurricane/Error.h" -#include "hurricane/DebugSession.h" -#include "hurricane/ViaLayer.h" -#include "hurricane/RoutingPad.h" -#include "crlcore/RoutingGauge.h" -#include "anabatic/Configuration.h" -#include "anabatic/AutoContactTerminal.h" -#include "anabatic/AutoContactTurn.h" -#include "anabatic/AutoHorizontal.h" -#include "anabatic/AutoVertical.h" +#include +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DebugSession.h" +#include "hurricane/ViaLayer.h" +#include "hurricane/RoutingPad.h" +#include "crlcore/RoutingGauge.h" +#include "anabatic/Configuration.h" +#include "anabatic/AutoContactTerminal.h" +#include "anabatic/AutoContactTurn.h" +#include "anabatic/AutoHorizontal.h" +#include "anabatic/AutoVertical.h" namespace Anabatic { @@ -33,8 +34,10 @@ namespace Anabatic { using std::min; using std::max; - using Hurricane::Error; + using std::abs; using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; using Hurricane::DebugSession; using Hurricane::ViaLayer; using Hurricane::RoutingPad; @@ -52,8 +55,6 @@ namespace Anabatic { DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); } DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); } Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); } - void AutoHorizontal::setDuSource ( DbU::Unit du ) { _horizontal->setDxSource(du); } - void AutoHorizontal::setDuTarget ( DbU::Unit du ) { _horizontal->setDxTarget(du); } string AutoHorizontal::_getTypeName () const { return "AutoHorizontal"; } @@ -130,6 +131,30 @@ namespace Anabatic { } + void AutoHorizontal::setDuSource ( DbU::Unit du ) + { + _horizontal->setDxSource(du); + if (abs(du) > getPitch()) + cerr << Warning( "AutoHorizontal::setDuSource(): Suspiciously big du=%s (should not exceed routing pitch %s)\n" + " On %s" + , DbU::getValueString(du).c_str() + , DbU::getValueString(getPitch()).c_str() + , getString(this).c_str() ) << endl; + } + + + void AutoHorizontal::setDuTarget ( DbU::Unit du ) + { + _horizontal->setDxTarget(du); + if (abs(du) > getPitch()) + cerr << Warning( "AutoHorizontal::setDuTarget(): Suspiciously big du=%s (should not exceed routing pitch %s)\n" + " On %s" + , DbU::getValueString(du).c_str() + , DbU::getValueString(getPitch()).c_str() + , getString(this).c_str() ) << endl; + } + + Interval AutoHorizontal::getSourceConstraints ( Flags flags ) const { if (flags & Flags::NativeConstraints) { @@ -487,17 +512,9 @@ namespace Anabatic { void AutoHorizontal::updateOrient () { if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) { - cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl; - if (isAtMinArea()) { - DbU::Unit sourceX = _horizontal->getSourceX(); - DbU::Unit targetX = _horizontal->getTargetX(); - _horizontal->invert(); - setDuSource( sourceX - getSourceU() ); - setDuTarget( targetX - getTargetU() ); - } else { - _horizontal->invert(); - } - cdebug_log(145,0) << "updateOrient() " << this << " (after S/T swap)" << endl; + cdebug_log(149,1) << "updateOrient() " << this << " (before S/T swap)" << endl; + _horizontal->invert(); + cdebug_log(149,0) << "updateOrient() " << this << " (after S/T swap)" << endl; uint64_t spinFlags = _flags & SegDepthSpin; unsetFlags( SegDepthSpin ); @@ -515,6 +532,7 @@ namespace Anabatic { unsetFlags( SegStrongTerminal ); if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal ); if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal ); + cdebug_tabw(149,-1); } } diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index e42cceb4..f31b1ead 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -679,8 +679,12 @@ namespace Anabatic { void AutoSegment::revalidate () { + DebugSession::open( getNet(), 159, 160 ); cdebug_log(149,0) << "AutoSegment::revalidate() " << this << endl; - if (not isInvalidated()) return; + if (not isInvalidated()) { + DebugSession::close(); + return; + } cdebug_tabw(149,1); @@ -715,9 +719,9 @@ namespace Anabatic { } Interval oldSpan = Interval( _sourcePosition, _targetPosition ); - if (not expandToMinLength(oldSpan)) { - unexpandToMinLength(); - } + if (_flags & SegCreated) oldSpan.makeEmpty(); + expandToMinLength( oldSpan ); + if (_flags & SegAtMinArea) unexpandToMinLength(); updatePositions(); unsigned int observerFlags = Revalidate; @@ -735,6 +739,7 @@ namespace Anabatic { cdebug_log(149,0) << "Updated: " << this << endl; cdebug_tabw(149,-1); + DebugSession::close(); } @@ -806,7 +811,7 @@ namespace Anabatic { // and not (flags & Flags::NoMinLength) // and (flags & Flags::Target) // and (getMinimalLength(depth) != 0.0) - // and isMiddleStack() ) { + // and isNearMinArea() ) { // DbU::Unit realLength = getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength ) // + getAnchoredLength(); // if (realLength + cap < getMinimalLength(depth)) { @@ -1613,52 +1618,15 @@ namespace Anabatic { } - bool AutoSegment::isMiddleStack () const + bool AutoSegment::isNearMinArea () const { - cdebug_log(149,0) << "AutoSegment::isMiddleStack() - " << this << endl; - if (not isCanonical()) return false; + cdebug_log(149,0) << "AutoSegment::isNearMinArea() - " << this << endl; if (isNonPref()) return false; if (isGlobal()) { if (getLength() > getPPitch()) return false; cdebug_log(149,0) << "| Considering this global anyway because it is too short. " << endl; } - AutoContact* source = getAutoSource(); - AutoContact* target = getAutoTarget(); - if (not source or not target) { - cdebug_log(149,0) << "| false, missing source or target (in creation?). " << endl; - return false; - } - if (isSpinTopOrBottom()) { - cdebug_log(149,0) << "| false, neither spin top nor bottom. " << endl; - return false; - } - if (not (source->isTerminal() xor target->isTerminal())) { - if (source->isTerminal() and target->isTerminal()) { - cdebug_log(149,0) << "| false, source & target are terminals. " << endl; - return false; - } - if (source->isTurn()) { - AutoSegment* perpandicular = source->getPerpandicular( this ); - if (perpandicular->isNonPref() and (perpandicular->getAnchoredLength() != 0)) { - cdebug_log(149,0) << "| false, perpandicular is non-pref and non-zero. " << this << endl; - return false; - } - } else if (target->isTurn()) { - AutoSegment* perpandicular = target->getPerpandicular( this ); - if (perpandicular->isNonPref() and (perpandicular->getAnchoredLength() != 0)) { - cdebug_log(149,0) << "| false, perpandicular is non-pref and non-zero. " << this << endl; - return false; - } - } else if ((source->isHTee() or target->isHTee()) and isHorizontal()) { - cdebug_log(149,0) << "| false, S/T HTee+Terminal and horizontal. " << this << endl; - return false; - } else if ((source->isVTee() or target->isVTee()) and isVertical()) { - cdebug_log(149,0) << "| false, S/T VTee+Terminal and vertical. " << this << endl; - return false; - } - } - DbU::Unit sourceAxis = 0; DbU::Unit targetAxis = 0; getEndAxes( sourceAxis, targetAxis ); @@ -1666,43 +1634,38 @@ namespace Anabatic { cdebug_log(149,0) << "| Canonical axis length superior to P-Pitch " << this << endl; return false; } - cdebug_log(149,0) << " Middle stack or terminal bound." << endl; + cdebug_log(149,0) << " Length below P-Pitch." << endl; return true; } - bool AutoSegment::isUnderMinLength () const + void AutoSegment::expandToMinLength ( Interval span ) { - return false; - // cdebug_log(149,0) << "AutoSegment::isUnderMinLength() - " << this << endl; - // if (not isMiddleStack()) return false; - // DbU::Unit spanLength = getSpanLength(); - // DbU::Unit minimalLength = getMinimalLength( Session::getLayerDepth( getLayer() )); - // cdebug_log(149,0) << " span=" << DbU::getValueString(spanLength) - // << " < min=" << DbU::getValueString(minimalLength)<< endl; - // return spanLength < minimalLength; - } - - - bool AutoSegment::expandToMinLength ( Interval span ) - { - if (not isMiddleStack()) return false; + if (not isNearMinArea()) return; + DebugSession::open( getNet(), 149, 160 ); cdebug_log(149,1) << "AutoSegment::expandToMinLength() " << this << endl; cdebug_log(149,0) << "In span=" << span << endl; cdebug_log(149,0) << "Before: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly )) << " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly )) << "]" << endl; - DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly ); - DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly ); - DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap; - DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() )); - if (techMinLength <= segMinLength) { - cdebug_log(149,0) << "Above minimal length (" << DbU::getValueString(segMinLength) - << " >= " << DbU::getValueString(techMinLength) << ")" << endl; + DbU::Unit halfMinSpacing = getLayer()->getMinimalSpacing() / 2; + DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::LayerCapOnly ); + DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::LayerCapOnly ); + DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap; + DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() )); + cdebug_log(149,0) << "Minimal length " << DbU::getValueString(techMinLength) + << " vs. current length " << DbU::getValueString(segMinLength) << endl; + if (segMinLength >= techMinLength) { + if (segMinLength == techMinLength) + setFlags( SegAtMinArea ); cdebug_tabw(149,-1); - return false; + DebugSession::close(); + return; } + sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly ); + targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly ); + segMinLength = getAnchoredLength() + sourceCap + targetCap; DbU::Unit oneGrid = DbU::fromGrid( 1 ); DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap; @@ -1712,11 +1675,20 @@ namespace Anabatic { if (sourceExpand % oneGrid) sourceExpand -= oneGrid + sourceExpand % oneGrid; if (not span.isEmpty()) { - DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand); + DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand + halfMinSpacing); if (shiftLeft < 0) { + if (targetExpand + shiftLeft < targetCap) + shiftLeft = targetCap - targetExpand; targetExpand += shiftLeft; sourceExpand += shiftLeft; } + DbU::Unit shiftRight = span.getVMin() - (getSourceU() + sourceExpand - halfMinSpacing); + if (shiftRight > 0) { + if (sourceExpand + shiftRight < sourceCap) + shiftRight = - sourceExpand - sourceCap; + targetExpand += shiftRight; + sourceExpand += shiftRight; + } } setDuSource( sourceExpand ); setDuTarget( targetExpand ); @@ -1727,18 +1699,75 @@ namespace Anabatic { << "] expand:" << DbU::getValueString(techMinLength - segMinLength)<< endl; setFlags( SegAtMinArea ); cdebug_tabw(149,-1); - return true; + DebugSession::close(); } - bool AutoSegment::unexpandToMinLength () + void AutoSegment::unexpandToMinLength () { - if (not isAtMinArea()) return false; cdebug_log(149,0) << "AutoSegment::unexpandToMinLength() " << this << endl; + // Note: sourceU is a negative number. + // targetU is a positive number. + // But *both* "cap" are positives. + DbU::Unit duSource = getDuSource(); + DbU::Unit duTarget = getDuTarget(); + DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly ); + DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly ); + DbU::Unit segLength = getTargetU() - getSourceU(); + DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap; + DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() )); + + cdebug_log(149,0) << "* Anchored length " << DbU::getValueString(getAnchoredLength()) << endl; + cdebug_log(149,0) << "* Source cap " << DbU::getValueString(sourceCap) << endl; + cdebug_log(149,0) << "* Target cap " << DbU::getValueString(targetCap) << endl; + cdebug_log(149,0) << "* duSource " << DbU::getValueString(duSource) << endl; + cdebug_log(149,0) << "* duTarget " << DbU::getValueString(duTarget) << endl; + + if ((duSource == 0) and (duTarget == 0)) { + cdebug_log(149,0) << "Already reset!" << endl; + return; + } + + if (segLength <= techMinLength) { + cdebug_log(149,0) << "Still at min area, do nothing." << endl; + return; + } + + if (segMinLength > techMinLength) { + cdebug_log(149,0) << "Complete reset." << endl; + setDuSource( 0 ); + setDuTarget( 0 ); + unsetFlags( SegAtMinArea ); + return; + } + + DbU::Unit shrink = (getAnchoredLength() + duTarget - duSource) - techMinLength; + if (shrink < 0) { + cerr << Warning( "AutoSegment::unexpandToMinLength(): Negative shrink %s, but forbidden to expand.\n" + " On %s" + , DbU::getValueString(shrink).c_str() + , getString(this).c_str() + ) << endl; + return; + } + + DbU::Unit margin = -duSource - sourceCap; + if (shrink <= margin) { + cdebug_log(149,0) << "Shrink source of " << DbU::getValueString(shrink) << endl; + duSource += shrink; + setDuSource( duSource ); + return; + } + setDuSource( 0 ); - setDuTarget( 0 ); - unsetFlags( SegAtMinArea ); - return true; + cdebug_log(149,0) << "Shrink target of " << DbU::getValueString(shrink) << endl; + margin = duTarget - targetCap; + if (margin > shrink) + setDuTarget( duTarget - shrink ); + else { + cdebug_log(149,0) << "Target reset" << endl; + setDuTarget( 0 ); + } } @@ -2303,6 +2332,8 @@ namespace Anabatic { setWidth( hside ); source->setSizes( hside, vside ); target->setSizes( hside, vside ); + setDuSource( 0 ); + setDuTarget( 0 ); success = true; } @@ -2711,6 +2742,7 @@ namespace Anabatic { state += isFixed () ?" F":" -"; state += isFixedAxis () ? "X": "-"; state += isUnsetAxis () ? "u": "-"; + state += isAtMinArea () ? "a": "-"; state += isStrap () ? "S": "-"; state += isUnbreakable () ? "U": "-"; state += isCanonical () ? "C": "-"; diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index 67231413..d23b3aa6 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -16,6 +16,7 @@ #include #include "hurricane/Bug.h" +#include "hurricane/Warning.h" #include "hurricane/ViaLayer.h" #include "hurricane/Vertical.h" #include "crlcore/RoutingGauge.h" @@ -29,8 +30,10 @@ namespace Anabatic { using std::min; using std::max; - using Hurricane::Error; + using std::abs; using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; using Hurricane::ViaLayer; @@ -46,8 +49,6 @@ namespace Anabatic { DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); } DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); } Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); } - void AutoVertical::setDuSource ( DbU::Unit du ) { _vertical->setDySource(du); } - void AutoVertical::setDuTarget ( DbU::Unit du ) { _vertical->setDyTarget(du); } string AutoVertical::_getTypeName () const { return "AutoVertical"; } @@ -117,6 +118,30 @@ namespace Anabatic { } + void AutoVertical::setDuSource ( DbU::Unit du ) + { + _vertical->setDySource(du); + if (abs(du) > getPitch()) + cerr << Warning( "AutoVertical::setDuSource(): Suspiciously big du=%s (should not exceed routing pitch %s)\n" + " On %s" + , DbU::getValueString(du).c_str() + , DbU::getValueString(getPitch()).c_str() + , getString(this).c_str() ) << endl; + } + + + void AutoVertical::setDuTarget ( DbU::Unit du ) + { + _vertical->setDyTarget(du); + if (abs(du) > getPitch()) + cerr << Warning( "AutoVertical::setDuTarget(): Suspiciously big du=%s (should not exceed routing pitch %s)\n" + " On %s" + , DbU::getValueString(du).c_str() + , DbU::getValueString(getPitch()).c_str() + , getString(this).c_str() ) << endl; + } + + Interval AutoVertical::getSourceConstraints ( Flags flags ) const { if (flags & Flags::NativeConstraints) { @@ -382,10 +407,6 @@ namespace Anabatic { if (_vertical->getTargetY() < _vertical->getSourceY()) { cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl; _vertical->invert(); - DbU::Unit duSource = getDuSource(); - DbU::Unit duTarget = getDuTarget(); - setDuSource( -duTarget ); - setDuTarget( -duSource ); unsigned int spinFlags = _flags & SegDepthSpin; unsetFlags( SegDepthSpin ); diff --git a/anabatic/src/anabatic/AutoHorizontal.h b/anabatic/src/anabatic/AutoHorizontal.h index 07b882ee..ccab6c6e 100644 --- a/anabatic/src/anabatic/AutoHorizontal.h +++ b/anabatic/src/anabatic/AutoHorizontal.h @@ -14,11 +14,9 @@ // +-----------------------------------------------------------------+ -#ifndef ANABATIC_AUTOHORIZONTAL_H -#define ANABATIC_AUTOHORIZONTAL_H - -#include "hurricane/Horizontal.h" -#include "anabatic/AutoSegment.h" +#pragma once +#include "hurricane/Horizontal.h" +#include "anabatic/AutoSegment.h" namespace Anabatic { @@ -91,6 +89,3 @@ namespace Anabatic { INSPECTOR_P_SUPPORT(Anabatic::AutoHorizontal); - - -#endif // ANABATIC_AUTOHORIZONTAL_H diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index aaba2bfd..55803bfc 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -216,7 +216,6 @@ namespace Anabatic { inline bool isSpinBottom () const; inline bool isSpinTopOrBottom () const; inline bool isReduced () const; - bool isUnderMinLength () const; inline bool isStrap () const; inline bool isDogleg () const; inline bool isUnbound () const; @@ -227,7 +226,7 @@ namespace Anabatic { inline bool isUnsetAxis () const; inline bool isSlackened () const; inline bool isUserDefined () const; - bool isMiddleStack () const; + bool isNearMinArea () const; bool isReduceCandidate () const; bool isUTurn () const; inline bool isAnalog () const; @@ -340,8 +339,8 @@ namespace Anabatic { bool bloatStackedStrap (); bool reduce ( Flags flags=Flags::WithPerpands ); bool raise (); - bool expandToMinLength ( Interval ); - bool unexpandToMinLength (); + void expandToMinLength ( Interval ); + void unexpandToMinLength (); // Canonical Modifiers. AutoSegment* canonize ( Flags flags=Flags::NoFlags ); virtual void invalidate ( Flags flags=Flags::Propagate ); diff --git a/anabatic/src/anabatic/AutoVertical.h b/anabatic/src/anabatic/AutoVertical.h index c10a00ae..153a6b01 100644 --- a/anabatic/src/anabatic/AutoVertical.h +++ b/anabatic/src/anabatic/AutoVertical.h @@ -14,11 +14,9 @@ // +-----------------------------------------------------------------+ -#ifndef ANABATIC_AUTOVERTICAL_H -#define ANABATIC_AUTOVERTICAL_H - -#include "hurricane/Vertical.h" -#include "anabatic/AutoSegment.h" +#pragma once +#include "hurricane/Vertical.h" +#include "anabatic/AutoSegment.h" namespace Anabatic { @@ -91,6 +89,3 @@ namespace Anabatic { INSPECTOR_P_SUPPORT(Anabatic::AutoVertical); - - -#endif // ANABATIC_AUTOHORIZONTAL_H diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index 56c688cd..615f4886 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -864,16 +864,6 @@ namespace Katana { if (getState() > Anabatic::EngineDriving) return; cdebug_tabw(155,1); - - openSession(); - for ( RoutingPlane* plane : _routingPlanes ) { - for ( Track* track : plane->getTracks() ) { - //track->expandMinArea(); - track->repair(); - } - } - Session::close(); - setState( Anabatic::EngineDriving ); _gutKatana(); diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 231bbb1e..8efc0fee 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -790,7 +790,12 @@ namespace Katana { if (flags & Flags::PreRoutedStage) { _katana->setFixedPreRouted(); } + Session::revalidate(); + for ( RoutingPlane* plane : _katana->getRoutingPlanes() ) { + for ( Track* track : plane->getTracks() ) + track->repair(); + } Session::revalidate(); Session::get()->isEmpty(); diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 95b338ca..b83d06f7 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -121,19 +121,25 @@ namespace { void GapSet::merge ( size_t i ) { - TrackElement* element = _track->getSegment( i ); + TrackElement* element = _track->getSegment( i ); + DbU::Unit segSourceU = element->getSourceU()+_halfSpacing; + DbU::Unit segTargetU = element->getTargetU()-_halfSpacing; if (_spans.empty()) { - cdebug_log(159,0) << "GapSet::merge() new range " << i + cdebug_log(159,0) << "GapSet::merge() new range [" + << DbU::getValueString(segSourceU) << " " + << DbU::getValueString(segTargetU) << "] " + << i << " " << _track->getSegment(i) << endl; _spans.push_back( make_pair(i,i) ); return; } - size_t ispan = 0; - DbU::Unit segSourceU = element->getSourceU()+_halfSpacing; - DbU::Unit segTargetU = element->getTargetU()-_halfSpacing; - cdebug_log(159,0) << "GapSet::merge() " << element << endl; + size_t ispan = 0; + cdebug_log(159,0) << "GapSet::merge() [" + << DbU::getValueString(segSourceU) << " " + << DbU::getValueString(segTargetU) << "] " + << element << endl; for ( ; ispan<_spans.size() ; ++ispan ) { if (targetU(ispan) >= segSourceU) { if (targetU(ispan) >= segTargetU) { @@ -1005,11 +1011,12 @@ namespace Katana { uint32_t Track::repair () const { - //if ((getIndex() == 1011) and isHorizontal()) DebugSession::open( 150, 160 ); + //if ((getIndex() == 3473) and isHorizontal()) DebugSession::open( 150, 160 ); cdebug_log(159,0) << "Track::repair() " << this << endl; if (_segments.empty()) { fillHole( getMin(), getMax() ); + //if ((getIndex() == 3473) and isHorizontal()) DebugSession::close(); return 0; } DbU::Unit minSpacing = getLayer()->getMinimalSpacing(); @@ -1024,6 +1031,7 @@ namespace Katana { GapSet gapsetCurr ( this ); for ( size_t i=0 ; i<_segments.size()-1 ; i++ ) { cdebug_log(159,0) << "[" << i << "] " << _segments[i] << endl; + if (_segments[i]->isNonPref()) continue; netChange = false; gapsetCurr.merge( i ); if ( (_segments[i]->getNet() != _segments[i+1]->getNet()) @@ -1033,19 +1041,25 @@ namespace Katana { spacing = gapsetCurr.spansSourceU() - gapsetPrev.spansTargetU(); if (spacing < minSpacing) { spacing = minSpacing - spacing; - AutoSegment* prev = _segments[ gapsetPrev.span(gapsetPrev.size()-1).second ]->base(); + TrackElement* element = _segments[ gapsetPrev.span(gapsetPrev.size()-1).second ]; + AutoSegment* prev = element->base(); if (prev and (prev->getDuTarget() >= spacing)) { prev->setDuSource( prev->getDuSource() - spacing ); prev->setDuTarget( prev->getDuTarget() - spacing ); - cerr << Warning( " Track::repair(): Enlarging narrow gap in %s near (shift left):\n %s" + element->invalidate(); + cerr << Warning( "Track::repair(): Enlarging narrow gap in %s near (shift left):\n" + " %s" , getString(this).c_str() , getString(prev).c_str() ) << endl; } else { - AutoSegment* curr = _segments[ gapsetCurr.span(0).first ]->base(); + TrackElement* element = _segments[ gapsetCurr.span(0).first ]; + AutoSegment* curr = element->base(); if (curr and (-curr->getDuSource() >= spacing)) { curr->setDuSource( curr->getDuSource() + spacing ); curr->setDuTarget( curr->getDuTarget() + spacing ); - cerr << Warning( " Track::repair(): Enlarging narrow gap in %s near (shift right):\n %s" + element->invalidate(); + cerr << Warning( "Track::repair(): Enlarging narrow gap in %s near (shift right):\n" + " %s" , getString(this).c_str() , getString(curr).c_str() ) << endl; } @@ -1074,14 +1088,15 @@ namespace Katana { << j+1 << "=[" << DbU::getValueString(gapsetCurr.sourceU(j+1)) << " " << DbU::getValueString(gapsetCurr.targetU(j+1)) << "]" << endl; if (gapsetCurr.span(j+1).first >= _segments.size()) { - cerr << Error("gapsetCurr.span(j+1).first >= _segments.size()") << endl; + cerr << Bug("Track::repair(): Assersion gapsetCurr.span(j+1).first < _segments.size() is false.") << endl; } else { - AutoSegment* first = _segments[gapsetCurr.span(j+1).first]->base(); + TrackElement* element = _segments[gapsetCurr.span(j+1).first]; + AutoSegment* first = element->base(); cdebug_log(159,0) << "spacing:" << DbU::getValueString(spacing) << " " << first << endl; if (first == NULL) { - cerr << Error("null first, NOT correcting gap") << endl; - } else { + cerr << Bug("Track::repair(): Base of first element is NULL, *unable* to correct gap.") << endl; + } else if (not first->isNonPref()) { for ( AutoSegment* segment : first->getAligneds() ) { if (segment->getSourcePosition() < first->getSourcePosition()) first = segment; @@ -1091,9 +1106,10 @@ namespace Katana { cdebug_log(159,0) << "duSource:" << DbU::getValueString(first->getDuSource()) << endl; //first->setDuSource( first->getDuSource() - spacing - minSpacing/2 ); first->setDuSource( first->getDuSource() - spacing ); + element->invalidate(); } ++gaps; - cerr << Warning( " Track::repair(): Closing same net gap in %s near:\n %s" + cerr << Warning( "Track::repair(): Closing same net gap in %s near:\n %s" , getString(this).c_str() , getString(_segments[(i) ? i-1 : 0]).c_str() ) << endl; cdebug_log(159,0) << first << endl; @@ -1124,7 +1140,7 @@ namespace Katana { if (spacing > 10*getLayerGauge()->getPitch()) fillHole( lastTargetU, getMax() ); - //if ((getIndex() == 1011) and isHorizontal()) DebugSession::close(); + //if ((getIndex() == 3473) and isHorizontal()) DebugSession::close(); return gaps; } @@ -1215,7 +1231,9 @@ namespace Katana { ++j; continue; } - if (not _segments[j]->base()->isMiddleStack()) continue; + if ((j > 0) and (_segments[j-1]->getNet() == _segments[j]->getNet())) continue; + if ((j+1 < _segments.size()) and (_segments[j+1]->getNet() == _segments[j]->getNet())) continue; + if (not _segments[j]->base()->isNearMinArea()) continue; if (_segments[j]->base()->getSpanLength() < techMinLength) { cerr << Error( "Below minimal length/area for %s:\n length:%s, minimal length:%s" , getString(_segments[j]).c_str() diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 938a3f02..ff7483e6 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -478,6 +478,8 @@ namespace Katana { void TrackSegment::revalidate () { + DebugSession::open( getNet(), 159, 160 ); + unsetFlags( TElemCreated ); cdebug_log(159,0) << "revalidate() - " << this << endl; @@ -501,6 +503,8 @@ namespace Katana { } } unsetFlags( TElemInvalidated ); + + DebugSession::close(); } diff --git a/katana/src/katana/KatanaEngine.h b/katana/src/katana/KatanaEngine.h index 948f187c..a76acab9 100644 --- a/katana/src/katana/KatanaEngine.h +++ b/katana/src/katana/KatanaEngine.h @@ -100,6 +100,8 @@ namespace Katana { getPostEventCb (); inline NegociateWindow* getNegociateWindow (); inline size_t getRoutingPlanesSize () const; + inline const std::vector& + getRoutingPlanes () const; RoutingPlane* getRoutingPlaneByIndex ( size_t index ) const; RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const; Track* getTrackByPosition ( const Layer*, DbU::Unit axis, uint32_t mode=Constant::Nearest ) const; @@ -216,6 +218,8 @@ namespace Katana { inline Block* KatanaEngine::getBlock ( size_t i ) const { return (i < _blocks.size()) ? _blocks[i] : NULL; } inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; } inline size_t KatanaEngine::getRoutingPlanesSize () const { return _routingPlanes.size(); } + inline const std::vector& + KatanaEngine::getRoutingPlanes () const { return _routingPlanes; } inline void KatanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } inline void KatanaEngine::setStage ( uint32_t stage ) { _stage=stage; } inline void KatanaEngine::setEventLimit ( uint64_t limit ) { _configuration->setEventsLimit(limit); }