General review & redesign of the "minimum area checking" for segments.
* Change: In AutoHorizontal::setDuSource() & ::setDuTarget() (& AutoVertical), check that the requested "du" is less than a pitch (this is not an upper bound). Issue a warning if not true. * Change: In AutoSegment::revalidate(), when passing the previous span interval to expandToMinLength(), if we are in creation stage, make it empty because it has no sense yet and can lead to a lock in a too narrow span. Change the coupled behavior of expandToMinLength() vs. unexpandToMinLength(), the call to "unexpand" will be done on AutoSegments that are flagged with SegAtMinArea, instead of using the return value of "expand". This way we control across multiple revalidate() if a segment can be "unexpanded". * Bug: In AutoSegment::expandToMinLength(), not only try to shift left if we are beyoond the max bound but also to the right if we are below the min bound. the span on the target and source were miscalculated, we must add the half-minimal distance to get the span inside the Track. * Change: In AutoSegment::isMiddleStack(), rename into isNearMinArea() as we check for any *small length* set of AutoSegments and not only the one part of a middle stack. In some rare instances, two aligned segments can nevertheless be too short. * Bug: In AutoSegment::reduceDoglegLayer(), when finding a reduced segment also reset it's duSource & duTarget because it will no longer be an isolated strip of metal. * Change: In AutoHorizontal::updateOrient(), when there is a source/target swap, no need to exchange the dxSource and dxTarget extentions. * Change: In AutoHorizontal::setDuSource() & ::setDuTarget(), check for du bigger than the pitch, which should never occur and display a warning. Same modification in AutoVertical. * Change: In Track::repair(), now invalidate the shifted segments to ensure cache coherency with the TrackElement. Do not take AutoSegment in non-preferred direction into account, and especially do not try to resize them. Now, invalidate the corrected segments (see below). * Change: In KatanaEngine::finalizeLayout(), move the track repair stage from here into NegociateWidow::run(). This way we avoid the false warning about segment overlap in the data-base final check. The false warning was because the AutoSegment where shifted but not invalidated/revalidated leading to a cache incoherency in the TrackElement. Now they *are* invalidated and updated. * Bug: In Track::checkMinArea(), do not check for minimal area when a segment is overlapping a same net neighbor. To avoid false minimum area violation warnings.
This commit is contained in:
parent
ab13a02eed
commit
42bf5d29d4
|
@ -14,18 +14,19 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#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 <algorithm>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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": "-";
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -100,6 +100,8 @@ namespace Katana {
|
|||
getPostEventCb ();
|
||||
inline NegociateWindow* getNegociateWindow ();
|
||||
inline size_t getRoutingPlanesSize () const;
|
||||
inline const std::vector<RoutingPlane*>&
|
||||
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<RoutingPlane*>&
|
||||
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); }
|
||||
|
|
Loading…
Reference in New Issue