Rewrite support for minimum area metal wires (stacked VIAs).
We use the segments extensions (dxTarget & dyTarget) to enlarge if needed the segments. This new implementation is completely at Anabatic level and should not be seen (i.e. managed) at Katana level. * Change: In AutoHorizontal & AutoVertical, change the semantic of getSourceU() and getTargetU(). formerly they where the end position of the segment (with extension included), now they gives the position of the anchor contacts, that is the axis of the perpandiculars. * New: AutoSegment::getLength() is still a proxy toward the Segment::getLength() which returns the length of segment with dxSource & dxTarget. We introduce a getAnchoredlength() which returns the length between the centers of the S/T anchors. That is axis to axis. This is this length which is now used througout Anabatic. * New: In AutoSegment::_extentionCaps, add a fourth item to hold the segment minimal length (to respect minimal area given the wire width). * New: In AutoSegment::getExtensionCap(), if the segment has a non-zero S/T extension, returns it instead of the S/T contact extension *if it is greated*. The check of the extension can be disabled by the Flag::NoSegExt flag. * Change: In AutoSegment::isMiddleStack(), security check on the presence of source and targets. More accurate detection of perpandicular in "same layer" with a non-zero length, So the area is OK, even with a short segment. * New: AutoSegment::expandToMinLength(), check if a segment is under the minimal length and expand it if need be by playing with the dxTarget & dxSource. Tag minimal segments with the AutoSegment::SegAtMinArea flag. Also try to keep the segment *inside* it's former (supposedly wider) interval. * New: AutoSegment::unexpandToMinLength(), to be called on a formerly minimal sized segment which as grown up. Reset it's S/T extensions to zero and unset the flag SegAtMinArea. * Change: In AutoHorizontal::updateOrient(), when the extension are non-zero, also swap them if needed, to keep the exact footprint of the segment. * New: In AutoSegment::revalidate(), check that the segment respect the minimal length (area), and expand it if needed. Conversely, if the segment has grown up from a minimal length state, reset it's extensions to zero. * Change: In Anabatic::Session::revalidate(), invalidateds segments are now sorted in such a way that the "middle stack" ones are revalidateds last. Not recall 100% why... * New: In Katana::TrackCost, add a computation of the free interval length we are into (if any). Not used yet, keep it for future use. * Change: In KatanaEngine::finalizeLayout(), remove the call to segments minimum area protection. It is now obsoleted by the new implementation in Anabatic. * Change: In Track::check(), call the minimum size/area checker Track::checkMinArea().
This commit is contained in:
parent
0326d513bd
commit
08d1db5dd6
|
@ -1355,7 +1355,7 @@ namespace Anabatic {
|
||||||
set<const Layer*> connectedLayers;
|
set<const Layer*> connectedLayers;
|
||||||
|
|
||||||
forEach ( Segment*, segment, net->getSegments() ) {
|
forEach ( Segment*, segment, net->getSegments() ) {
|
||||||
if (segment->getLength()) {
|
if (segment->getAnchoredLength()) {
|
||||||
if (net->isExternal()) {
|
if (net->isExternal()) {
|
||||||
NetExternalComponents::setExternal( *segment );
|
NetExternalComponents::setExternal( *segment );
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ namespace Anabatic {
|
||||||
size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
|
size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
|
||||||
DbU::Unit length;
|
DbU::Unit length;
|
||||||
if (segment->isLocal()) {
|
if (segment->isLocal()) {
|
||||||
length = segment->getLength();
|
length = segment->getAnchoredLength();
|
||||||
lengths[depth] += length;
|
lengths[depth] += length;
|
||||||
|
|
||||||
DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength;
|
DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength;
|
||||||
|
|
|
@ -47,8 +47,8 @@ namespace Anabatic {
|
||||||
Segment* AutoHorizontal::base () { return _horizontal; }
|
Segment* AutoHorizontal::base () { return _horizontal; }
|
||||||
Segment* AutoHorizontal::base () const { return _horizontal; }
|
Segment* AutoHorizontal::base () const { return _horizontal; }
|
||||||
Horizontal* AutoHorizontal::getHorizontal () { return _horizontal; }
|
Horizontal* AutoHorizontal::getHorizontal () { return _horizontal; }
|
||||||
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSourceX(); }
|
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSource()->getX(); }
|
||||||
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTargetX(); }
|
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTarget()->getX(); }
|
||||||
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
|
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
|
||||||
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
|
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
|
||||||
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }
|
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }
|
||||||
|
@ -335,11 +335,11 @@ namespace Anabatic {
|
||||||
|
|
||||||
cdebug_tabw(149,1);
|
cdebug_tabw(149,1);
|
||||||
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
||||||
cdebug_log(149,0) << "test:" << (getLength() < 5*getPitch()) << endl;
|
cdebug_log(149,0) << "test:" << (getAnchoredLength() < 5*getPitch()) << endl;
|
||||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
|
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl;
|
||||||
|
|
||||||
if (height >= 4*getPitch()) {
|
if (height >= 4*getPitch()) {
|
||||||
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch())) {
|
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < 5*getPitch())) {
|
||||||
cdebug_log(149,0) << "Too short terminal segment to slacken." << endl;
|
cdebug_log(149,0) << "Too short terminal segment to slacken." << endl;
|
||||||
cdebug_tabw(149,-1);
|
cdebug_tabw(149,-1);
|
||||||
return false;
|
return false;
|
||||||
|
@ -486,9 +486,18 @@ namespace Anabatic {
|
||||||
|
|
||||||
void AutoHorizontal::updateOrient ()
|
void AutoHorizontal::updateOrient ()
|
||||||
{
|
{
|
||||||
if (_horizontal->getTargetX() < _horizontal->getSourceX()) {
|
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) {
|
||||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||||
_horizontal->invert();
|
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;
|
||||||
|
|
||||||
uint64_t spinFlags = _flags & SegDepthSpin;
|
uint64_t spinFlags = _flags & SegDepthSpin;
|
||||||
unsetFlags( SegDepthSpin );
|
unsetFlags( SegDepthSpin );
|
||||||
|
@ -512,8 +521,8 @@ namespace Anabatic {
|
||||||
|
|
||||||
void AutoHorizontal::updatePositions ()
|
void AutoHorizontal::updatePositions ()
|
||||||
{
|
{
|
||||||
_sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
|
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source);
|
||||||
_targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
|
_targetPosition = getTargetU() + getExtensionCap(Flags::Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -533,8 +542,8 @@ namespace Anabatic {
|
||||||
bool AutoHorizontal::checkPositions () const
|
bool AutoHorizontal::checkPositions () const
|
||||||
{
|
{
|
||||||
bool coherency = true;
|
bool coherency = true;
|
||||||
DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
|
DbU::Unit sourcePosition = _horizontal->getSource()->getX() - getExtensionCap(Flags::Source);
|
||||||
DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
|
DbU::Unit targetPosition = _horizontal->getTarget()->getX() + getExtensionCap(Flags::Target);
|
||||||
|
|
||||||
if ( _sourcePosition != sourcePosition ) {
|
if ( _sourcePosition != sourcePosition ) {
|
||||||
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl;
|
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl;
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace Anabatic {
|
||||||
if ( deltaUnit < 0 ) return true; // Smallest source first.
|
if ( deltaUnit < 0 ) return true; // Smallest source first.
|
||||||
if ( deltaUnit > 0 ) return false;
|
if ( deltaUnit > 0 ) return false;
|
||||||
|
|
||||||
deltaUnit = lhs->getLength() - rhs->getLength();
|
deltaUnit = lhs->getAnchoredLength() - rhs->getAnchoredLength();
|
||||||
if ( deltaUnit > 0 ) return true; // Longest first.
|
if ( deltaUnit > 0 ) return true; // Longest first.
|
||||||
if ( deltaUnit < 0 ) return false;
|
if ( deltaUnit < 0 ) return false;
|
||||||
|
|
||||||
|
@ -409,6 +409,22 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Class : "Anabatic::AutoSegment::CompareByRevalidate".
|
||||||
|
|
||||||
|
|
||||||
|
bool AutoSegment::CompareByRevalidate::operator() ( AutoSegment* lhs, AutoSegment* rhs ) const
|
||||||
|
{
|
||||||
|
if (lhs->isNonPref() xor rhs->isNonPref() ) return lhs->isNonPref();
|
||||||
|
|
||||||
|
DbU::Unit deltaLength = lhs->getAnchoredLength() - rhs->getAnchoredLength();
|
||||||
|
if (deltaLength > 0) return true; // Longest length first.
|
||||||
|
if (deltaLength < 0) return false;
|
||||||
|
|
||||||
|
return lhs->getId() < rhs->getId(); // Smallest Id first.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Class : "Anabatic::AutoSegment".
|
// Class : "Anabatic::AutoSegment".
|
||||||
|
|
||||||
|
@ -431,6 +447,7 @@ namespace Anabatic {
|
||||||
//cerr << "AutoSegment::_initialize()" << endl;
|
//cerr << "AutoSegment::_initialize()" << endl;
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
|
DbU::Unit twoGrid = DbU::fromGrid( 2 );
|
||||||
for ( size_t depth=0 ; depth<Session::getDepth() ; ++depth ) {
|
for ( size_t depth=0 ; depth<Session::getDepth() ; ++depth ) {
|
||||||
DbU::Unit* viaToTopCap = new DbU::Unit ( 0 );
|
DbU::Unit* viaToTopCap = new DbU::Unit ( 0 );
|
||||||
DbU::Unit* viaToBottomCap = new DbU::Unit ( 0 );
|
DbU::Unit* viaToBottomCap = new DbU::Unit ( 0 );
|
||||||
|
@ -460,6 +477,9 @@ namespace Anabatic {
|
||||||
double minimalArea = routingLayer->getMinimalArea();
|
double minimalArea = routingLayer->getMinimalArea();
|
||||||
if (minimalArea != 0.0) {
|
if (minimalArea != 0.0) {
|
||||||
*minimalLength = DbU::fromMicrons( minimalArea / DbU::toMicrons( Session::getWireWidth(depth) ) );
|
*minimalLength = DbU::fromMicrons( minimalArea / DbU::toMicrons( Session::getWireWidth(depth) ) );
|
||||||
|
DbU::Unit modulo = *minimalLength % twoGrid;
|
||||||
|
if (modulo)
|
||||||
|
*minimalLength += twoGrid - modulo;
|
||||||
}
|
}
|
||||||
|
|
||||||
//cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl;
|
//cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl;
|
||||||
|
@ -684,6 +704,10 @@ namespace Anabatic {
|
||||||
incReduceds();
|
incReduceds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Interval oldSpan = Interval( _sourcePosition, _targetPosition );
|
||||||
|
if (not expandToMinLength(oldSpan)) {
|
||||||
|
unexpandToMinLength();
|
||||||
|
}
|
||||||
updatePositions();
|
updatePositions();
|
||||||
|
|
||||||
unsigned int observerFlags = Revalidate;
|
unsigned int observerFlags = Revalidate;
|
||||||
|
@ -736,25 +760,50 @@ namespace Anabatic {
|
||||||
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
||||||
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
||||||
else cap = getViaToSameCap (depth);
|
else cap = getViaToSameCap (depth);
|
||||||
cdebug_log(150,0) << "getExtensionCap(): flags:" << getFlags()
|
cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
|
||||||
<< " VIA cap:" << DbU::getValueString(cap)
|
<< " VIA cap:" << DbU::getValueString(cap)
|
||||||
<< " t:" << (getFlags() & SegSourceBottom)
|
<< " t:" << (getFlags() & SegSourceBottom)
|
||||||
<< " b:" << (getFlags() & SegSourceTop)
|
<< " b:" << (getFlags() & SegSourceTop)
|
||||||
<< endl;
|
<< endl;
|
||||||
|
if (not (flags & Flags::NoSegExt)) {
|
||||||
|
cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl;
|
||||||
|
if (-getDuSource() > cap) {
|
||||||
|
cap = -getDuSource();
|
||||||
|
cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & Flags::Target) {
|
if (flags & Flags::Target) {
|
||||||
if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
|
if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
|
||||||
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
|
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
|
||||||
else cap = getViaToSameCap (depth);
|
else cap = getViaToSameCap (depth);
|
||||||
}
|
cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
|
||||||
|
<< " VIA cap:" << DbU::getValueString(cap)
|
||||||
if (not isCreated() and (getMinimalLength(depth) != 0.0) and isMiddleStack()) {
|
<< " t:" << (getFlags() & SegSourceBottom)
|
||||||
if (getLength() < getMinimalLength(depth)) {
|
<< " b:" << (getFlags() & SegSourceTop)
|
||||||
cap = std::max( cap, getMinimalLength(depth)/2 );
|
<< endl;
|
||||||
|
if (not (flags & Flags::NoSegExt)) {
|
||||||
|
cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl;
|
||||||
|
if (getDuTarget() > cap) {
|
||||||
|
cap = getDuTarget();
|
||||||
|
cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if ( not isCreated()
|
||||||
|
// and not (flags & Flags::NoMinLength)
|
||||||
|
// and (flags & Flags::Target)
|
||||||
|
// and (getMinimalLength(depth) != 0.0)
|
||||||
|
// and isMiddleStack() ) {
|
||||||
|
// DbU::Unit realLength = getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
|
||||||
|
// + getAnchoredLength();
|
||||||
|
// if (realLength + cap < getMinimalLength(depth)) {
|
||||||
|
// cap = getMinimalLength(depth) - realLength;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (getLayer()->isSymbolic() and (cap < getWidth()/2)) cap = getWidth()/2;
|
if (getLayer()->isSymbolic() and (cap < getWidth()/2)) cap = getWidth()/2;
|
||||||
if (not (flags & Flags::LayerCapOnly)) cap += getLayer()->getMinimalSpacing()/2;
|
if (not (flags & Flags::LayerCapOnly)) cap += getLayer()->getMinimalSpacing()/2;
|
||||||
return cap;
|
return cap;
|
||||||
|
@ -1329,7 +1378,7 @@ namespace Anabatic {
|
||||||
if (terminalMin != terminalMax)
|
if (terminalMin != terminalMax)
|
||||||
attractors.addAttractor( terminalMax );
|
attractors.addAttractor( terminalMax );
|
||||||
}
|
}
|
||||||
} else if (autoSegment->isLongLocal() or (autoSegment->getLength() > getPPitch()*20)) {
|
} else if (autoSegment->isLongLocal() or (autoSegment->getAnchoredLength() > getPPitch()*20)) {
|
||||||
cdebug_log(145,0) << "Used as long global attractor." << endl;
|
cdebug_log(145,0) << "Used as long global attractor." << endl;
|
||||||
|
|
||||||
DbU::Unit perpandMin = autoSegment->getSourceU();
|
DbU::Unit perpandMin = autoSegment->getSourceU();
|
||||||
|
@ -1555,16 +1604,95 @@ namespace Anabatic {
|
||||||
|
|
||||||
bool AutoSegment::isMiddleStack () const
|
bool AutoSegment::isMiddleStack () const
|
||||||
{
|
{
|
||||||
if (isGlobal()) return false;
|
cdebug_log(149,0) << "AutoSegment::isMiddleStack() - " << this << endl;
|
||||||
if (isSpinTopOrBottom()) return false;
|
if (isGlobal() or isNonPref()) return false;
|
||||||
|
|
||||||
AutoContact* source = getAutoSource();
|
AutoContact* source = getAutoSource();
|
||||||
AutoContact* target = getAutoTarget();
|
AutoContact* target = getAutoTarget();
|
||||||
|
if (not source or not target) return false;
|
||||||
|
if (isSpinTopOrBottom()) return false;
|
||||||
|
if (not source->isTurn() and not source->isTerminal()) return false;
|
||||||
|
if (not target->isTurn() and not target->isTerminal()) 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cdebug_log(149,0) << " Middle stack or terminal bound." << endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (not source->isTurn() or not target->isTurn()) return false;
|
|
||||||
if (source->getPerpandicular(this)->isNonPref()) return false;
|
|
||||||
if (target->getPerpandicular(this)->isNonPref()) return false;
|
|
||||||
|
|
||||||
|
bool AutoSegment::isUnderMinLength () const
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
cdebug_tabw(149,-1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap;
|
||||||
|
DbU::Unit sourceExpand = - (techMinLength - segMinLength) / 2 - sourceCap;
|
||||||
|
if (not span.isEmpty()) {
|
||||||
|
DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand);
|
||||||
|
if (shiftLeft < 0) {
|
||||||
|
targetExpand += shiftLeft;
|
||||||
|
sourceExpand += shiftLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setDuSource( sourceExpand );
|
||||||
|
setDuTarget( targetExpand );
|
||||||
|
cdebug_log(149,0) << "sourceExpand=" << DbU::getValueString(sourceExpand)
|
||||||
|
<< " targetExpand=" << DbU::getValueString(targetExpand) << endl;
|
||||||
|
cdebug_log(149,0) << "After: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly ))
|
||||||
|
<< " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly ))
|
||||||
|
<< "] expand:" << DbU::getValueString(techMinLength - segMinLength)<< endl;
|
||||||
|
setFlags( SegAtMinArea );
|
||||||
|
cdebug_tabw(149,-1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool AutoSegment::unexpandToMinLength ()
|
||||||
|
{
|
||||||
|
if (not isAtMinArea()) return false;
|
||||||
|
cdebug_log(149,0) << "AutoSegment::unexpandToMinLength() " << this << endl;
|
||||||
|
setDuSource( 0 );
|
||||||
|
setDuTarget( 0 );
|
||||||
|
unsetFlags( SegAtMinArea );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1614,8 +1742,8 @@ namespace Anabatic {
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
cdebug_log(159,0) << " length:" << DbU::getValueString(getLength()) << endl;
|
cdebug_log(159,0) << " length:" << DbU::getValueString(getAnchoredLength()) << endl;
|
||||||
if (getLength() >= (Session::getPitch(perpandicularDepth) * 2)) return false;
|
if (getAnchoredLength() >= (Session::getPitch(perpandicularDepth) * 2)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1653,7 +1781,7 @@ namespace Anabatic {
|
||||||
else if (isSpinTop ()) ++perpandicularDepth;
|
else if (isSpinTop ()) ++perpandicularDepth;
|
||||||
else return true;
|
else return true;
|
||||||
|
|
||||||
return (getLength() >= (Session::getPitch(perpandicularDepth) * 2));
|
return (getAnchoredLength() >= (Session::getPitch(perpandicularDepth) * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2846,7 +2974,7 @@ namespace Anabatic {
|
||||||
exploreds.insert( seed->getAutoSource() );
|
exploreds.insert( seed->getAutoSource() );
|
||||||
exploreds.insert( seed->getAutoTarget() );
|
exploreds.insert( seed->getAutoTarget() );
|
||||||
|
|
||||||
if (seed->getLength()) {
|
if (seed->getAnchoredLength()) {
|
||||||
if (flags & Flags::Superior) stack.push_back( seed->getAutoTarget() );
|
if (flags & Flags::Superior) stack.push_back( seed->getAutoTarget() );
|
||||||
else stack.push_back( seed->getAutoSource() );
|
else stack.push_back( seed->getAutoSource() );
|
||||||
} else {
|
} else {
|
||||||
|
@ -2871,7 +2999,7 @@ namespace Anabatic {
|
||||||
AutoSegment* autoSegment = Session::lookup( segment );
|
AutoSegment* autoSegment = Session::lookup( segment );
|
||||||
if (not autoSegment) continue;
|
if (not autoSegment) continue;
|
||||||
|
|
||||||
if (not autoSegment->getLength()) {
|
if (not autoSegment->getAnchoredLength()) {
|
||||||
AutoContact* contact = autoSegment->getAutoSource();
|
AutoContact* contact = autoSegment->getAutoSource();
|
||||||
if (contact and (contact != currentContact)) {
|
if (contact and (contact != currentContact)) {
|
||||||
if (exploreds.find(contact) == exploreds.end())
|
if (exploreds.find(contact) == exploreds.end())
|
||||||
|
|
|
@ -41,8 +41,8 @@ namespace Anabatic {
|
||||||
Segment* AutoVertical::base () { return _vertical; }
|
Segment* AutoVertical::base () { return _vertical; }
|
||||||
Segment* AutoVertical::base () const { return _vertical; }
|
Segment* AutoVertical::base () const { return _vertical; }
|
||||||
Vertical* AutoVertical::getVertical () { return _vertical; }
|
Vertical* AutoVertical::getVertical () { return _vertical; }
|
||||||
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSourceY(); }
|
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSource()->getY(); }
|
||||||
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTargetY(); }
|
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTarget()->getY(); }
|
||||||
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
|
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
|
||||||
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
|
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
|
||||||
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }
|
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }
|
||||||
|
@ -268,13 +268,13 @@ namespace Anabatic {
|
||||||
|
|
||||||
if (not isDrag()) {
|
if (not isDrag()) {
|
||||||
if ( not isStrongTerminal()
|
if ( not isStrongTerminal()
|
||||||
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) )
|
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < getPitch()*5)) )
|
||||||
{ cdebug_tabw(149,-1); return false; }
|
{ cdebug_tabw(149,-1); return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
||||||
cdebug_log(149,0) << "test:" << (getLength() < getPitch()*5) << endl;
|
cdebug_log(149,0) << "test:" << (getAnchoredLength() < getPitch()*5) << endl;
|
||||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
|
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl;
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
bool sourceSlackened = false;
|
bool sourceSlackened = false;
|
||||||
|
@ -382,6 +382,10 @@ namespace Anabatic {
|
||||||
if (_vertical->getTargetY() < _vertical->getSourceY()) {
|
if (_vertical->getTargetY() < _vertical->getSourceY()) {
|
||||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||||
_vertical->invert();
|
_vertical->invert();
|
||||||
|
DbU::Unit duSource = getDuSource();
|
||||||
|
DbU::Unit duTarget = getDuTarget();
|
||||||
|
setDuSource( -duTarget );
|
||||||
|
setDuTarget( -duSource );
|
||||||
|
|
||||||
unsigned int spinFlags = _flags & SegDepthSpin;
|
unsigned int spinFlags = _flags & SegDepthSpin;
|
||||||
unsetFlags( SegDepthSpin );
|
unsetFlags( SegDepthSpin );
|
||||||
|
@ -405,8 +409,8 @@ namespace Anabatic {
|
||||||
|
|
||||||
void AutoVertical::updatePositions ()
|
void AutoVertical::updatePositions ()
|
||||||
{
|
{
|
||||||
_sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
|
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source);
|
||||||
_targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
|
_targetPosition = getTargetU() + getExtensionCap(Flags::Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -426,8 +430,8 @@ namespace Anabatic {
|
||||||
bool AutoVertical::checkPositions () const
|
bool AutoVertical::checkPositions () const
|
||||||
{
|
{
|
||||||
bool coherency = true;
|
bool coherency = true;
|
||||||
DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
|
DbU::Unit sourcePosition = _vertical->getSource()->getY() - getExtensionCap(Flags::Source);
|
||||||
DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
|
DbU::Unit targetPosition = _vertical->getTarget()->getY() + getExtensionCap(Flags::Target);
|
||||||
|
|
||||||
if ( _sourcePosition != sourcePosition ) {
|
if ( _sourcePosition != sourcePosition ) {
|
||||||
cerr << Error ( "%s\n Source position incoherency: "
|
cerr << Error ( "%s\n Source position incoherency: "
|
||||||
|
|
|
@ -122,6 +122,8 @@ namespace Anabatic {
|
||||||
const BaseFlags Flags::UseNonPref = (1L << 34);
|
const BaseFlags Flags::UseNonPref = (1L << 34);
|
||||||
const BaseFlags Flags::Force = (1L << 35);
|
const BaseFlags Flags::Force = (1L << 35);
|
||||||
const BaseFlags Flags::LayerCapOnly = (1L << 36);
|
const BaseFlags Flags::LayerCapOnly = (1L << 36);
|
||||||
|
const BaseFlags Flags::NoMinLength = (1L << 37);
|
||||||
|
const BaseFlags Flags::NoSegExt = (1L << 38);
|
||||||
|
|
||||||
|
|
||||||
Flags::~Flags ()
|
Flags::~Flags ()
|
||||||
|
|
|
@ -754,7 +754,7 @@ namespace Anabatic {
|
||||||
if (not segment->isStrongTerminal()) locals.push_back( segment );
|
if (not segment->isStrongTerminal()) locals.push_back( segment );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( (segment->getLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
|
if ( (segment->getAnchoredLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
|
||||||
locals.push_back( segment );
|
locals.push_back( segment );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1737,7 +1737,7 @@ namespace Anabatic {
|
||||||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||||
|
|
||||||
// HARDCODED VALUE.
|
// HARDCODED VALUE.
|
||||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||||
addToFixSegments( globalSegment );
|
addToFixSegments( globalSegment );
|
||||||
|
|
||||||
if (getConnexity().fields.globals < 2) {
|
if (getConnexity().fields.globals < 2) {
|
||||||
|
|
|
@ -318,7 +318,7 @@ namespace Anabatic {
|
||||||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||||
|
|
||||||
// HARDCODED VALUE.
|
// HARDCODED VALUE.
|
||||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||||
addToFixSegments( globalSegment );
|
addToFixSegments( globalSegment );
|
||||||
|
|
||||||
if (getConnexity().fields.globals < 2) {
|
if (getConnexity().fields.globals < 2) {
|
||||||
|
|
|
@ -577,7 +577,7 @@ namespace Anabatic {
|
||||||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||||
|
|
||||||
// HARDCODED VALUE.
|
// HARDCODED VALUE.
|
||||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||||
addToFixSegments( globalSegment );
|
addToFixSegments( globalSegment );
|
||||||
|
|
||||||
if (getConnexity().fields.globals < 2) {
|
if (getConnexity().fields.globals < 2) {
|
||||||
|
|
|
@ -259,6 +259,8 @@ namespace Anabatic {
|
||||||
cdebug_log(145,0) << "_segmentInvalidateds.size(): " << _segmentInvalidateds.size() << endl;
|
cdebug_log(145,0) << "_segmentInvalidateds.size(): " << _segmentInvalidateds.size() << endl;
|
||||||
|
|
||||||
_segmentRevalidateds.clear();
|
_segmentRevalidateds.clear();
|
||||||
|
std::sort( _segmentInvalidateds.begin(), _segmentInvalidateds.end()
|
||||||
|
, AutoSegment::CompareByRevalidate() );
|
||||||
for ( size_t i=0 ; i < _segmentInvalidateds.size() ; ++i, ++count ) {
|
for ( size_t i=0 ; i < _segmentInvalidateds.size() ; ++i, ++count ) {
|
||||||
_segmentInvalidateds[i]->revalidate();
|
_segmentInvalidateds[i]->revalidate();
|
||||||
if ( not _destroyedSegments.empty()
|
if ( not _destroyedSegments.empty()
|
||||||
|
|
|
@ -107,6 +107,7 @@ namespace Anabatic {
|
||||||
static const uint64_t SegShortNet = (1L<<35);
|
static const uint64_t SegShortNet = (1L<<35);
|
||||||
static const uint64_t SegUnbreakable = (1L<<36);
|
static const uint64_t SegUnbreakable = (1L<<36);
|
||||||
static const uint64_t SegNonPref = (1L<<37);
|
static const uint64_t SegNonPref = (1L<<37);
|
||||||
|
static const uint64_t SegAtMinArea = (1L<<38);
|
||||||
// Masks.
|
// Masks.
|
||||||
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||||
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||||
|
@ -173,6 +174,7 @@ namespace Anabatic {
|
||||||
inline DbU::Unit getContactWidth () const;
|
inline DbU::Unit getContactWidth () const;
|
||||||
inline DbU::Unit getLength () const;
|
inline DbU::Unit getLength () const;
|
||||||
inline DbU::Unit getSpanLength () const;
|
inline DbU::Unit getSpanLength () const;
|
||||||
|
inline DbU::Unit getAnchoredLength () const;
|
||||||
inline DbU::Unit getSourcePosition () const;
|
inline DbU::Unit getSourcePosition () const;
|
||||||
inline DbU::Unit getTargetPosition () const;
|
inline DbU::Unit getTargetPosition () const;
|
||||||
inline DbU::Unit getSourceX () const;
|
inline DbU::Unit getSourceX () const;
|
||||||
|
@ -200,6 +202,7 @@ namespace Anabatic {
|
||||||
inline bool isUnbreakable () const;
|
inline bool isUnbreakable () const;
|
||||||
inline bool isNonPref () const;
|
inline bool isNonPref () const;
|
||||||
inline bool isDrag () const;
|
inline bool isDrag () const;
|
||||||
|
inline bool isAtMinArea () const;
|
||||||
inline bool isNotSourceAligned () const;
|
inline bool isNotSourceAligned () const;
|
||||||
inline bool isNotTargetAligned () const;
|
inline bool isNotTargetAligned () const;
|
||||||
inline bool isNotAligned () const;
|
inline bool isNotAligned () const;
|
||||||
|
@ -212,6 +215,7 @@ namespace Anabatic {
|
||||||
inline bool isSpinBottom () const;
|
inline bool isSpinBottom () const;
|
||||||
inline bool isSpinTopOrBottom () const;
|
inline bool isSpinTopOrBottom () const;
|
||||||
inline bool isReduced () const;
|
inline bool isReduced () const;
|
||||||
|
bool isUnderMinLength () const;
|
||||||
inline bool isStrap () const;
|
inline bool isStrap () const;
|
||||||
inline bool isDogleg () const;
|
inline bool isDogleg () const;
|
||||||
inline bool isUnbound () const;
|
inline bool isUnbound () const;
|
||||||
|
@ -332,6 +336,8 @@ namespace Anabatic {
|
||||||
bool bloatStackedStrap ();
|
bool bloatStackedStrap ();
|
||||||
bool reduce ();
|
bool reduce ();
|
||||||
bool raise ();
|
bool raise ();
|
||||||
|
bool expandToMinLength ( Interval );
|
||||||
|
bool unexpandToMinLength ();
|
||||||
// Canonical Modifiers.
|
// Canonical Modifiers.
|
||||||
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||||
virtual void invalidate ( Flags flags=Flags::Propagate );
|
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||||
|
@ -425,6 +431,10 @@ namespace Anabatic {
|
||||||
struct CompareBySourceU : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
struct CompareBySourceU : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||||
};
|
};
|
||||||
|
public:
|
||||||
|
struct CompareByRevalidate : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||||
|
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
||||||
typedef std::set<AutoSegment*,CompareId> IdSet;
|
typedef std::set<AutoSegment*,CompareId> IdSet;
|
||||||
|
@ -526,6 +536,7 @@ namespace Anabatic {
|
||||||
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
|
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
|
||||||
inline bool AutoSegment::isTerminal () const { return (_rpDistance == 0); }
|
inline bool AutoSegment::isTerminal () const { return (_rpDistance == 0); }
|
||||||
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
|
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
|
||||||
|
inline bool AutoSegment::isAtMinArea () const { return _flags & SegAtMinArea; }
|
||||||
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
|
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
|
||||||
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
|
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
|
||||||
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
|
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
|
||||||
|
@ -564,6 +575,7 @@ namespace Anabatic {
|
||||||
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
|
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
|
||||||
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
|
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
|
||||||
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
|
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
|
||||||
|
inline DbU::Unit AutoSegment::getAnchoredLength () const { return std::abs(getTargetU() - getSourceU()); }
|
||||||
|
|
||||||
inline void AutoSegment::setLayer ( size_t depth )
|
inline void AutoSegment::setLayer ( size_t depth )
|
||||||
{
|
{
|
||||||
|
@ -579,8 +591,8 @@ namespace Anabatic {
|
||||||
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
|
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
|
||||||
|
|
||||||
inline DbU::Unit AutoSegment::getSpanLength () const
|
inline DbU::Unit AutoSegment::getSpanLength () const
|
||||||
{ return getLength() + getExtensionCap( Flags::Source|Flags::LayerCapOnly )
|
{ return getAnchoredLength() + getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
|
||||||
+ getExtensionCap( Flags::Target|Flags::LayerCapOnly );
|
+ getExtensionCap( Flags::Target|Flags::LayerCapOnly|Flags::NoMinLength );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AutoSegment::setParent ( AutoSegment* parent )
|
inline void AutoSegment::setParent ( AutoSegment* parent )
|
||||||
|
|
|
@ -103,6 +103,8 @@ namespace Anabatic {
|
||||||
static const BaseFlags UseNonPref ;
|
static const BaseFlags UseNonPref ;
|
||||||
static const BaseFlags Force ;
|
static const BaseFlags Force ;
|
||||||
static const BaseFlags LayerCapOnly ;
|
static const BaseFlags LayerCapOnly ;
|
||||||
|
static const BaseFlags NoMinLength ;
|
||||||
|
static const BaseFlags NoSegExt ;
|
||||||
public:
|
public:
|
||||||
inline Flags ( uint64_t flags = NoFlags );
|
inline Flags ( uint64_t flags = NoFlags );
|
||||||
inline Flags ( const Hurricane::BaseFlags& );
|
inline Flags ( const Hurricane::BaseFlags& );
|
||||||
|
|
|
@ -844,13 +844,13 @@ namespace Katana {
|
||||||
|
|
||||||
cdebug_tabw(155,1);
|
cdebug_tabw(155,1);
|
||||||
|
|
||||||
openSession();
|
// openSession();
|
||||||
for ( RoutingPlane* plane : _routingPlanes ) {
|
// for ( RoutingPlane* plane : _routingPlanes ) {
|
||||||
for ( Track* track : plane->getTracks() ) {
|
// for ( Track* track : plane->getTracks() ) {
|
||||||
track->expandMinArea();
|
// track->expandMinArea();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
Session::close();
|
// Session::close();
|
||||||
|
|
||||||
setState( Anabatic::EngineDriving );
|
setState( Anabatic::EngineDriving );
|
||||||
_gutKatana();
|
_gutKatana();
|
||||||
|
|
|
@ -324,6 +324,25 @@ namespace Katana {
|
||||||
TrackElement* trackSegment = lookup( revalidateds[i] );
|
TrackElement* trackSegment = lookup( revalidateds[i] );
|
||||||
if (trackSegment) trackSegment->reschedule( 0 );
|
if (trackSegment) trackSegment->reschedule( 0 );
|
||||||
}
|
}
|
||||||
|
// if (revalidateds[i]->isUnderMinLength()) {
|
||||||
|
// cdebug_log(159,0) << "Session: under min length:" << revalidateds[i] << endl;
|
||||||
|
// revalidateds[i]->expandToMinLength();
|
||||||
|
// TrackElement* trackSegment = lookup( revalidateds[i] );
|
||||||
|
// if (trackSegment) {
|
||||||
|
// trackSegment->invalidate();
|
||||||
|
// trackSegment->reschedule( 0 );
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// if (revalidateds[i]->isAtMinArea()) {
|
||||||
|
// if (revalidateds[i]->unexpandToMinLength()) {
|
||||||
|
// TrackElement* trackSegment = lookup( revalidateds[i] );
|
||||||
|
// if (trackSegment) {
|
||||||
|
// trackSegment->invalidate();
|
||||||
|
// trackSegment->reschedule( 0 );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
if (revalidateds[i]->canReduce()) {
|
if (revalidateds[i]->canReduce()) {
|
||||||
revalidateds[i]->reduce();
|
revalidateds[i]->reduce();
|
||||||
TrackElement* trackSegment = lookup( revalidateds[i] );
|
TrackElement* trackSegment = lookup( revalidateds[i] );
|
||||||
|
|
|
@ -373,8 +373,12 @@ namespace Katana {
|
||||||
const Interval& interval = cost.getInterval();
|
const Interval& interval = cost.getInterval();
|
||||||
Interval freeInterval = getFreeInterval( interval.getCenter(), cost.getNet() );
|
Interval freeInterval = getFreeInterval( interval.getCenter(), cost.getNet() );
|
||||||
|
|
||||||
if (not freeInterval.contains(interval))
|
if (not freeInterval.contains(interval)) {
|
||||||
getOverlapBounds( cost.getInterval(), begin, end );
|
getOverlapBounds( cost.getInterval(), begin, end );
|
||||||
|
cost.setFreeLength( 0 );
|
||||||
|
} else {
|
||||||
|
cost.setFreeLength( freeInterval.getSize() );
|
||||||
|
}
|
||||||
cost.setTrack( const_cast<Track*>(this), begin, end );
|
cost.setTrack( const_cast<Track*>(this), begin, end );
|
||||||
|
|
||||||
cdebug_log(155,1) << "addOverlapCost() @" << DbU::getValueString(_axis)
|
cdebug_log(155,1) << "addOverlapCost() @" << DbU::getValueString(_axis)
|
||||||
|
@ -658,6 +662,8 @@ namespace Katana {
|
||||||
if (not holes)
|
if (not holes)
|
||||||
coherency = (checkOverlap(overlaps) == 0) and coherency;
|
coherency = (checkOverlap(overlaps) == 0) and coherency;
|
||||||
|
|
||||||
|
coherency = (checkMinArea() == 0) and coherency;
|
||||||
|
|
||||||
return coherency;
|
return coherency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,6 +873,30 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t Track::checkMinArea () const
|
||||||
|
{
|
||||||
|
if (_segments.empty()) return 0;
|
||||||
|
|
||||||
|
uint32_t nonMinArea = 0;
|
||||||
|
DbU::Unit techMinLength = AutoSegment::getMinimalLength( Session::getLayerDepth( getLayer() ));
|
||||||
|
for ( size_t j=0 ; j<_segments.size() ; ++j ) {
|
||||||
|
if (not _segments[j]->base() or not (_segments[j]->getDirection() & getDirection())) {
|
||||||
|
++j;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (not _segments[j]->base()->isMiddleStack()) 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()
|
||||||
|
, DbU::getValueString(_segments[j]->base()->getSpanLength()).c_str()
|
||||||
|
, DbU::getValueString(techMinLength).c_str() ) << endl;
|
||||||
|
++nonMinArea;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nonMinArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Track::expandMinArea ()
|
void Track::expandMinArea ()
|
||||||
{
|
{
|
||||||
if (_segments.empty()) return;
|
if (_segments.empty()) return;
|
||||||
|
|
|
@ -57,6 +57,7 @@ namespace Katana {
|
||||||
, _axisWeight (0)
|
, _axisWeight (0)
|
||||||
, _distanceToFixed (2*Session::getSliceHeight())
|
, _distanceToFixed (2*Session::getSliceHeight())
|
||||||
, _longuestOverlap (0)
|
, _longuestOverlap (0)
|
||||||
|
, _freeLength (DbU::Max)
|
||||||
, _dataState (0)
|
, _dataState (0)
|
||||||
, _ripupCount (0)
|
, _ripupCount (0)
|
||||||
, _selectFlags (NoFlags)
|
, _selectFlags (NoFlags)
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace Katana {
|
||||||
DbU::Unit getSourcePosition ( size_t index ) const;
|
DbU::Unit getSourcePosition ( size_t index ) const;
|
||||||
bool check ( uint32_t& overlaps, const char* message=NULL ) const;
|
bool check ( uint32_t& overlaps, const char* message=NULL ) const;
|
||||||
uint32_t checkOverlap ( uint32_t& overlaps ) const;
|
uint32_t checkOverlap ( uint32_t& overlaps ) const;
|
||||||
|
uint32_t checkMinArea () const;
|
||||||
void expandMinArea ();
|
void expandMinArea ();
|
||||||
inline void setLocalAssigned ( bool );
|
inline void setLocalAssigned ( bool );
|
||||||
void invalidate ();
|
void invalidate ();
|
||||||
|
|
|
@ -131,6 +131,7 @@ namespace Katana {
|
||||||
inline DbU::Unit getDeltaPerpand () const;
|
inline DbU::Unit getDeltaPerpand () const;
|
||||||
inline DbU::Unit getLongestOverlap () const;
|
inline DbU::Unit getLongestOverlap () const;
|
||||||
inline DbU::Unit getAxisWeight () const;
|
inline DbU::Unit getAxisWeight () const;
|
||||||
|
inline DbU::Unit getFreeLength () const;
|
||||||
inline int getRipupCount () const;
|
inline int getRipupCount () const;
|
||||||
inline uint32_t getDataState () const;
|
inline uint32_t getDataState () const;
|
||||||
inline uint32_t setFlags ( uint32_t );
|
inline uint32_t setFlags ( uint32_t );
|
||||||
|
@ -152,6 +153,7 @@ namespace Katana {
|
||||||
inline void incDeltaShared ( DbU::Unit );
|
inline void incDeltaShared ( DbU::Unit );
|
||||||
inline void incAxisWeight ( DbU::Unit );
|
inline void incAxisWeight ( DbU::Unit );
|
||||||
inline void setLonguestOverlap ( DbU::Unit );
|
inline void setLonguestOverlap ( DbU::Unit );
|
||||||
|
inline void setFreeLength ( DbU::Unit );
|
||||||
inline void mergeRipupCount ( int );
|
inline void mergeRipupCount ( int );
|
||||||
inline void mergeDataState ( uint32_t );
|
inline void mergeDataState ( uint32_t );
|
||||||
inline bool selectNextTrack ();
|
inline bool selectNextTrack ();
|
||||||
|
@ -183,6 +185,7 @@ namespace Katana {
|
||||||
DbU::Unit _axisWeight;
|
DbU::Unit _axisWeight;
|
||||||
DbU::Unit _distanceToFixed;
|
DbU::Unit _distanceToFixed;
|
||||||
DbU::Unit _longuestOverlap;
|
DbU::Unit _longuestOverlap;
|
||||||
|
DbU::Unit _freeLength;
|
||||||
uint32_t _dataState;
|
uint32_t _dataState;
|
||||||
int _ripupCount;
|
int _ripupCount;
|
||||||
uint32_t _selectFlags;
|
uint32_t _selectFlags;
|
||||||
|
@ -223,6 +226,7 @@ namespace Katana {
|
||||||
inline const Interval& TrackCost::getInterval2 () const { return _interval2; }
|
inline const Interval& TrackCost::getInterval2 () const { return _interval2; }
|
||||||
inline uint32_t TrackCost::getTerminals () const { return _terminals; }
|
inline uint32_t TrackCost::getTerminals () const { return _terminals; }
|
||||||
inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; }
|
inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; }
|
||||||
|
inline DbU::Unit TrackCost::getFreeLength () const { return _freeLength; }
|
||||||
inline DbU::Unit TrackCost::getDelta () const { return _delta; }
|
inline DbU::Unit TrackCost::getDelta () const { return _delta; }
|
||||||
inline DbU::Unit TrackCost::getAxisWeight () const { return _axisWeight; }
|
inline DbU::Unit TrackCost::getAxisWeight () const { return _axisWeight; }
|
||||||
inline int TrackCost::getRipupCount () const { return _ripupCount; }
|
inline int TrackCost::getRipupCount () const { return _ripupCount; }
|
||||||
|
@ -245,6 +249,7 @@ namespace Katana {
|
||||||
inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; }
|
inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; }
|
||||||
inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; }
|
inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; }
|
||||||
inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); }
|
inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); }
|
||||||
|
inline void TrackCost::setFreeLength ( DbU::Unit length ) { _freeLength = std::min( length , _freeLength ); }
|
||||||
inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); }
|
inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); }
|
||||||
inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); }
|
inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); }
|
||||||
inline string TrackCost::_getTypeName () const { return "TrackCost"; }
|
inline string TrackCost::_getTypeName () const { return "TrackCost"; }
|
||||||
|
|
Loading…
Reference in New Issue