Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel
This commit is contained in:
commit
77ecf5523d
|
@ -183,19 +183,26 @@ namespace Anabatic {
|
|||
|
||||
void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
|
||||
{
|
||||
cdebug_log(145,1) << "AutoContact::getDepthSpan() of " << this << endl;
|
||||
minDepth = (size_t)-1;
|
||||
maxDepth = 0;
|
||||
|
||||
Component* anchor = getAnchor ();
|
||||
if (anchor) {
|
||||
cdebug_log(145,0) << "* Anchor depth: "
|
||||
<< Session::getRoutingGauge()->getLayerDepth(anchor->getLayer())<< endl;
|
||||
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
||||
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
||||
}
|
||||
|
||||
for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
|
||||
cdebug_log(145,0) << "* segment depth: "
|
||||
<< Session::getRoutingGauge()->getLayerDepth(segment->getLayer())<< endl;
|
||||
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
|
||||
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -559,11 +559,11 @@ namespace Anabatic {
|
|||
if (delta > 1) {
|
||||
//_segment = _segment->makeDogleg( this );
|
||||
_segment->makeDogleg( this );
|
||||
cdebug_log(145,0) << "Update seg: " << _segment << endl;
|
||||
delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) );
|
||||
cdebug_log(145,0) << "Delta: " << delta << " Update seg: " << _segment << endl;
|
||||
}
|
||||
else if (delta == 0) setLayerAndWidth( delta, anchorDepth );
|
||||
else if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
|
||||
if (delta == 0) setLayerAndWidth( delta, anchorDepth );
|
||||
if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
|
||||
}
|
||||
_segment->invalidate( this );
|
||||
|
||||
|
|
|
@ -263,7 +263,9 @@ namespace Anabatic {
|
|||
setFlags( CntBadTopology );
|
||||
} else {
|
||||
if (delta > 1) {
|
||||
if (_horizontal1->isInvalidatedLayer()) {
|
||||
bool updateH1 = (_horizontal1->isInvalidatedLayer() and not _horizontal1->isNonPref())
|
||||
or _vertical1->isNonPref();
|
||||
if (updateH1) {
|
||||
//_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
|
||||
_horizontal1->makeDogleg(this);
|
||||
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -770,16 +775,16 @@ namespace Anabatic {
|
|||
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
||||
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
||||
else cap = getViaToSameCap (depth);
|
||||
cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
|
||||
<< " VIA cap:" << DbU::getValueString(cap)
|
||||
<< " t:" << (getFlags() & SegSourceBottom)
|
||||
<< " b:" << (getFlags() & SegSourceTop)
|
||||
<< endl;
|
||||
// cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
|
||||
// << " VIA cap:" << DbU::getValueString(cap)
|
||||
// << " t:" << (getFlags() & SegSourceBottom)
|
||||
// << " b:" << (getFlags() & SegSourceTop)
|
||||
// << endl;
|
||||
if (not (flags & Flags::NoSegExt)) {
|
||||
cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl;
|
||||
// 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;
|
||||
// cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -788,16 +793,16 @@ namespace Anabatic {
|
|||
if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
|
||||
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
|
||||
else cap = getViaToSameCap (depth);
|
||||
cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
|
||||
<< " VIA cap:" << DbU::getValueString(cap)
|
||||
<< " t:" << (getFlags() & SegSourceBottom)
|
||||
<< " b:" << (getFlags() & SegSourceTop)
|
||||
<< endl;
|
||||
// cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
|
||||
// << " VIA cap:" << DbU::getValueString(cap)
|
||||
// << " t:" << (getFlags() & SegSourceBottom)
|
||||
// << " b:" << (getFlags() & SegSourceTop)
|
||||
// << endl;
|
||||
if (not (flags & Flags::NoSegExt)) {
|
||||
cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl;
|
||||
// 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;
|
||||
// cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -901,12 +906,12 @@ namespace Anabatic {
|
|||
sourceAxis = getSourceU();
|
||||
targetAxis = getTargetU();
|
||||
|
||||
if (not isNotAligned()) {
|
||||
//if (not isNotAligned()) {
|
||||
for( AutoSegment* aligned : const_cast<AutoSegment*>(this)->getAligneds() ) {
|
||||
sourceAxis = std::min( sourceAxis, aligned->getSourceU() );
|
||||
targetAxis = std::min( targetAxis, aligned->getTargetU() );
|
||||
targetAxis = std::max( targetAxis, aligned->getTargetU() );
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1455,6 +1460,7 @@ namespace Anabatic {
|
|||
AutoSegment* AutoSegment::canonize ( Flags flags )
|
||||
{
|
||||
cdebug_log(149,0) << "canonize() - " << this << endl;
|
||||
if (Session::getAnabatic()->isCanonizeDisabled()) return this;
|
||||
|
||||
// if (isCanonical() and isGlobal()) {
|
||||
// cdebug_log(149,0) << "* " << this << " canonical" << endl;
|
||||
|
@ -1612,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 );
|
||||
|
@ -1665,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;
|
||||
|
@ -1711,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 );
|
||||
|
@ -1726,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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2302,6 +2332,8 @@ namespace Anabatic {
|
|||
setWidth( hside );
|
||||
source->setSizes( hside, vside );
|
||||
target->setSizes( hside, vside );
|
||||
setDuSource( 0 );
|
||||
setDuTarget( 0 );
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
@ -2710,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 );
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::DestroyGCell = (1L << 7);
|
||||
const BaseFlags Flags::DestroyBaseContact = (1L << 8);
|
||||
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
|
||||
const BaseFlags Flags::DisableCanonize = (1L << 10);
|
||||
// Flags for NetDatas objects states only.
|
||||
const BaseFlags Flags::GlobalFixed = (1L << 5);
|
||||
const BaseFlags Flags::GlobalEstimated = (1L << 6);
|
||||
|
|
|
@ -1343,6 +1343,26 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void GCell::postGlobalAnnotate ()
|
||||
{
|
||||
if (isInvalidated()) updateDensity();
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
RoutingLayerGauge* rlg = Session::getLayerGauge( depth );
|
||||
if (rlg->getType() & Constant::PinOnly) continue;
|
||||
if (_densities[depth] >= 0.9) {
|
||||
if (depth+2 < _depth) {
|
||||
Edge* edge = (rlg->getDirection() == Constant::Vertical) ? getNorthEdge()
|
||||
: getEastEdge();
|
||||
if (edge) {
|
||||
edge->reserveCapacity( 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GCell::addBlockage ( size_t depth, DbU::Unit length )
|
||||
{
|
||||
if (depth >= _depth) return;
|
||||
|
@ -1371,6 +1391,7 @@ namespace Anabatic {
|
|||
if (found) {
|
||||
cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
|
||||
_contacts.pop_back();
|
||||
_flags |= Flags::Invalidated;
|
||||
} else {
|
||||
cerr << Bug("%p:%s do not belong to %s."
|
||||
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
|
||||
|
@ -1404,6 +1425,7 @@ namespace Anabatic {
|
|||
, _getString().c_str(), getString(segment).c_str() ) << endl;
|
||||
|
||||
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
|
||||
_flags |= Flags::Invalidated;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1429,6 +1451,7 @@ namespace Anabatic {
|
|||
, getString(segment).c_str() ) << endl;
|
||||
|
||||
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
|
||||
_flags |= Flags::Invalidated;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1528,13 +1551,20 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
// Add the blockages.
|
||||
int contiguousNonSaturated = 0;
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
uLengths2[i] += _blockages[i];
|
||||
if (not i) continue;
|
||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.40*(float)(width*height)) {
|
||||
flags() |= Flags::GoStraight;
|
||||
//cerr << "| Set GoStraight on " << this << endl;
|
||||
}
|
||||
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
|
||||
continue;
|
||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height))
|
||||
contiguousNonSaturated = 0;
|
||||
else
|
||||
contiguousNonSaturated++;
|
||||
}
|
||||
if (contiguousNonSaturated < 2) {
|
||||
flags() |= Flags::GoStraight;
|
||||
//cerr << "| Set GoStraight on " << this << endl;
|
||||
}
|
||||
|
||||
// Compute the number of non pass-through tracks.
|
||||
|
@ -1880,6 +1910,13 @@ namespace Anabatic {
|
|||
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add( getSlot ( s.str(), &_densities[depth] ) );
|
||||
}
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
ostringstream s;
|
||||
const Layer* layer = rg->getRoutingLayer(depth);
|
||||
s << "_feedthroughs[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add( getSlot ( s.str(), &_feedthroughs[depth] ) );
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Rectilinear.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
|
@ -220,6 +221,7 @@ namespace Anabatic {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Rectilinear;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -367,6 +369,8 @@ namespace Anabatic {
|
|||
, _toFixSegments ()
|
||||
, _degree (0)
|
||||
, _isTwoMetals (false)
|
||||
, _sourceFlags (0)
|
||||
, _flags (0)
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -377,6 +381,8 @@ namespace Anabatic {
|
|||
void NetBuilder::clear ()
|
||||
{
|
||||
_connexity.connexity = 0;
|
||||
_sourceFlags = 0;
|
||||
_flags = 0;
|
||||
_topology = 0;
|
||||
_net = NULL;
|
||||
_netData = NULL;
|
||||
|
@ -403,11 +409,15 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt, Hook* fromHook, AutoContact* sourceContact )
|
||||
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt
|
||||
, Hook* fromHook
|
||||
, AutoContact* sourceContact
|
||||
, uint64_t sourceFlags )
|
||||
{
|
||||
clear();
|
||||
|
||||
_isTwoMetals = anbt->getConfiguration()->isTwoMetals();
|
||||
_sourceFlags = sourceFlags;
|
||||
_sourceContact = sourceContact;
|
||||
_fromHook = fromHook;
|
||||
|
||||
|
@ -470,6 +480,12 @@ namespace Anabatic {
|
|||
throw Error( mismatchGCell );
|
||||
}
|
||||
|
||||
if ( (_gcell->getDensity( Session::getDHorizontalDepth() ) > 0.9)
|
||||
or (_gcell->getDensity( Session::getDVerticalDepth () ) > 0.9)) {
|
||||
cdebug_log(145,0) << "Base layers blockeds, moving up" << endl;
|
||||
_flags |= ToUpperRouting;
|
||||
}
|
||||
|
||||
if (not _gcell->isMatrix()) {
|
||||
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
|
||||
cdebug_log(145,0) << "| " << gcell << endl;
|
||||
|
@ -489,11 +505,25 @@ namespace Anabatic {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (layer->getMask() == Session::getRoutingLayer(0)->getMask()) _connexity.fields.M1++; // M1 V
|
||||
else if (layer->getMask() == Session::getRoutingLayer(1)->getMask()) _connexity.fields.M2++; // M2 H
|
||||
else if (layer->getMask() == Session::getRoutingLayer(2)->getMask()) _connexity.fields.M3++; // M3 V
|
||||
else if (layer->getMask() == Session::getRoutingLayer(3)->getMask()) _connexity.fields.M2++; // M4 H
|
||||
else if (layer->getMask() == Session::getRoutingLayer(4)->getMask()) _connexity.fields.M3++; // M5 V
|
||||
bool isPin = (dynamic_cast<Pin*>( rp->getOccurrence().getEntity() ) != nullptr);
|
||||
size_t rpDepth = 0;
|
||||
for ( size_t depth=0 ; depth < Session::getRoutingGauge()->getDepth() ; ++depth ) {
|
||||
if (layer->getMask() == Session::getRoutingLayer(depth)->getMask()) {
|
||||
rpDepth = depth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((rpDepth > 0) and not isPin
|
||||
and not Session::getRoutingGauge()->isSuperPitched()) {
|
||||
_flags |= ToUpperRouting;
|
||||
cdebug_log(145,0) << "ToUpperRouting set, getFlags():" << getFlags() << endl;
|
||||
}
|
||||
|
||||
if (rpDepth == 0) _connexity.fields.M1++; // M1 V
|
||||
else if (rpDepth == 1) _connexity.fields.M2++; // M2 H
|
||||
else if (rpDepth == 2) _connexity.fields.M3++; // M3 V
|
||||
else if (rpDepth == 3) _connexity.fields.M2++; // M4 H
|
||||
else if (rpDepth == 4) _connexity.fields.M3++; // M5 V
|
||||
else {
|
||||
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
|
||||
, getString(layer->getName()).c_str()
|
||||
|
@ -502,7 +532,7 @@ namespace Anabatic {
|
|||
//continue;
|
||||
}
|
||||
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) _connexity.fields.Pin++;
|
||||
if (isPin) _connexity.fields.Pin++;
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "| Component to connect: " << anchor << endl;
|
||||
|
@ -553,6 +583,7 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "NetBuilder::push()" << endl;
|
||||
cdebug_log(145,0) << "* toHook: " << toHook << endl;
|
||||
cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl;
|
||||
cdebug_log(145,0) << "* flags:" << flags << endl;
|
||||
|
||||
if (not toHook or (toHook == _fromHook)) {
|
||||
if (contact) {
|
||||
|
@ -571,12 +602,60 @@ namespace Anabatic {
|
|||
Hook* toHookOpposite = getSegmentOppositeHook( toHook );
|
||||
cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl;
|
||||
cdebug_log(145,0) << "Pushing (from) " << contact << endl;
|
||||
_forks.push( toHookOpposite, contact );
|
||||
_forks.push( toHookOpposite, contact, getFlags() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::isInsideBlockage ( GCell* gcell, Component* rp ) const
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::isInsideBlockage() " << endl;
|
||||
cdebug_log(145,0) << rp << endl;
|
||||
cdebug_log(145,0) << rp->getLayer()->getMask() << endl;
|
||||
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
if (gcell->getDensity(rpDepth) < 0.5) {
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
Box rpBb = rp->getBoundingBox();
|
||||
Layer::Mask rpMask = rp->getLayer()->getBlockageLayer()->getMask();
|
||||
cdebug_log(145,0) << "rpBb: " << rpBb << endl;
|
||||
for ( Occurrence occurrence : getAnabatic()->getCell()->getOccurrencesUnder(rpBb) ) {
|
||||
cdebug_log(145,0) << "| " << occurrence.getEntity() << endl;
|
||||
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
|
||||
if (not component) continue;
|
||||
|
||||
const Layer* blockageLayer = component->getLayer();
|
||||
Box blockageBb = component->getBoundingBox();
|
||||
cdebug_log(145,0) << " Mask: " << blockageLayer->getMask() << endl;
|
||||
if ( blockageLayer->isBlockage()
|
||||
and (blockageLayer->getMask() == rpMask)) {
|
||||
occurrence.getPath().getTransformation().applyOn( blockageBb );
|
||||
cdebug_log(145,0) << " Bb: " << blockageBb << endl;
|
||||
if (blockageBb.contains(rpBb)) {
|
||||
cdebug_log(145,-1) << "* Inside " << component << endl;
|
||||
return true;
|
||||
}
|
||||
if (blockageBb.intersect(rpBb)) {
|
||||
cerr << Warning( "NetBuilder::isInsideBlockage(): RoutingPad is only partially inside blocked area.\n"
|
||||
" * %s\n"
|
||||
" * %s"
|
||||
, getString(rp).c_str()
|
||||
, getString(component).c_str()
|
||||
) << endl;
|
||||
cdebug_log(145,-1) << "* Partially inside " << component << endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void NetBuilder::construct ()
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
|
||||
|
@ -589,6 +668,8 @@ namespace Anabatic {
|
|||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
|
||||
<< " getFlags():" << getFlags() << endl;
|
||||
|
||||
if (not isTwoMetals()) {
|
||||
_southWestContact = NULL;
|
||||
|
@ -2374,6 +2455,7 @@ namespace Anabatic {
|
|||
|
||||
Hook* sourceHook = NULL;
|
||||
AutoContact* sourceContact = NULL;
|
||||
uint64_t sourceFlags = NoFlags;
|
||||
RoutingPads routingPads = net->getRoutingPads();
|
||||
size_t degree = routingPads.getSize();
|
||||
|
||||
|
@ -2412,7 +2494,7 @@ namespace Anabatic {
|
|||
++connecteds;
|
||||
segmentFound = true;
|
||||
|
||||
setStartHook( anabatic, hook, NULL );
|
||||
setStartHook( anabatic, hook, NULL, NoFlags );
|
||||
if (getStateG() == 1) {
|
||||
if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) {
|
||||
cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl;
|
||||
|
@ -2440,9 +2522,9 @@ namespace Anabatic {
|
|||
}
|
||||
cdebug_tabw(145,-1);
|
||||
|
||||
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
|
||||
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL,NoFlags).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
|
||||
|
||||
setStartHook( anabatic, startHook, NULL );
|
||||
setStartHook( anabatic, startHook, NULL, NoFlags );
|
||||
cdebug_log(145,0) << endl;
|
||||
cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl;
|
||||
cdebug_log(145,0) << endl;
|
||||
|
@ -2451,18 +2533,21 @@ namespace Anabatic {
|
|||
|
||||
sourceHook = _forks.getFrom ();
|
||||
sourceContact = _forks.getContact();
|
||||
sourceFlags = _forks.getFlags ();
|
||||
_forks.pop();
|
||||
|
||||
while ( sourceHook ) {
|
||||
setStartHook( anabatic, sourceHook, sourceContact );
|
||||
setStartHook( anabatic, sourceHook, sourceContact, sourceFlags );
|
||||
construct();
|
||||
|
||||
sourceHook = _forks.getFrom();
|
||||
sourceHook = _forks.getFrom ();
|
||||
sourceContact = _forks.getContact();
|
||||
sourceFlags = _forks.getFlags ();
|
||||
_forks.pop();
|
||||
|
||||
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
|
||||
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
|
||||
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
|
||||
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
|
||||
cdebug_log(145,0) << "Popping (flags) " << sourceFlags << endl;
|
||||
}
|
||||
|
||||
Session::revalidate();
|
||||
|
@ -2473,10 +2558,11 @@ namespace Anabatic {
|
|||
for ( ; iover != overconstraineds.end() ; ++iover ) {
|
||||
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
|
||||
}
|
||||
Session::revalidate();
|
||||
#endif
|
||||
|
||||
Session::revalidate();
|
||||
fixSegments();
|
||||
Session::revalidate();
|
||||
cdebug_tabw(145,-1);
|
||||
|
||||
//DebugSession::close();
|
||||
|
|
|
@ -104,6 +104,7 @@ namespace Anabatic {
|
|||
viaSide = Session::getViaWidth( rpDepth );
|
||||
}
|
||||
|
||||
#if THIS_IS_DISABLED
|
||||
// Non-M1 terminal or punctual M1 protections.
|
||||
if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) {
|
||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||
|
@ -177,17 +178,45 @@ namespace Anabatic {
|
|||
getRpLookup().insert( make_pair(rp,segment) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Non-M1 terminal or punctual M1 protections.
|
||||
if (isInsideBlockage(gcell,rp)) flags |= NoProtect;
|
||||
if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) {
|
||||
if (rpDepth == 0) rpDepth = 1;
|
||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||
if (irp == getRpLookup().end()) {
|
||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, sourcePosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
AutoContact* targetProtect = AutoContactTerminal::create( targetGCell
|
||||
, rp
|
||||
, rpLayer
|
||||
, targetPosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
sourceProtect->setFlags( CntFixed );
|
||||
targetProtect->setFlags( CntFixed );
|
||||
|
||||
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction, rpDepth );
|
||||
segment->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
getRpLookup().insert( make_pair(rp,segment) );
|
||||
}
|
||||
}
|
||||
|
||||
if (sourcePosition != targetPosition) {
|
||||
if (flags & DoSourceContact)
|
||||
source = AutoContactTerminal::create( sourceGCell
|
||||
source = AutoContactTerminal::create( gcell
|
||||
, rp
|
||||
, rpLayer
|
||||
, sourcePosition
|
||||
, viaSide, viaSide
|
||||
);
|
||||
if (flags & DoTargetContact)
|
||||
target = AutoContactTerminal::create( targetGCell
|
||||
target = AutoContactTerminal::create( gcell
|
||||
, rp
|
||||
, rpLayer
|
||||
, targetPosition
|
||||
|
@ -245,7 +274,7 @@ namespace Anabatic {
|
|||
if (flags & (VSmall|UseNonPref)) {
|
||||
cdebug_log(145,0) << "case: UseNonPref" << endl;
|
||||
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|useNonPref );
|
||||
rpSourceContact = subContact1;
|
||||
}
|
||||
|
@ -254,19 +283,19 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "case: HSmall" << endl;
|
||||
|
||||
AutoContact* subContact1 = rpSourceContact;
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
||||
rpSourceContact = subContact2;
|
||||
|
||||
if (flags & Punctual) {
|
||||
cdebug_log(145,0) << "case: HSmall + Punctual" << endl;
|
||||
subContact1 = subContact2;
|
||||
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Vertical );
|
||||
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Vertical, rpDepth+2 );
|
||||
|
||||
subContact1 = subContact2;
|
||||
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
||||
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
|
||||
|
||||
rpSourceContact = subContact2;
|
||||
}
|
||||
|
@ -277,12 +306,14 @@ namespace Anabatic {
|
|||
AutoContact* subContact1 = NULL;
|
||||
|
||||
if (flags & HAccess) {
|
||||
if (flags & HAccessEW)
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
else
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
cdebug_log(145,0) << "HAccess" << endl;
|
||||
if (flags & HAccessEW) {
|
||||
cdebug_log(145,0) << "HAccessEW" << endl;
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
} else
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical );
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical, rpDepth+1 );
|
||||
} else {
|
||||
#if OFFGRID_M2_DISABLED
|
||||
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
||||
|
@ -299,9 +330,14 @@ namespace Anabatic {
|
|||
rpSourceContact = subContact1;
|
||||
}
|
||||
#endif
|
||||
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
|
||||
if (Session::getRoutingGauge()->isSuperPitched()) {
|
||||
cdebug_log(145,0) << "Vertical access & super-pitched" << endl;
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
|
||||
} else {
|
||||
cdebug_log(145,0) << "Vertical access" << endl;
|
||||
subContact1 = rpSourceContact;
|
||||
}
|
||||
}
|
||||
rpSourceContact = subContact1;
|
||||
}
|
||||
|
@ -456,7 +492,15 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
|
||||
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
size_t hDepth = Session::getDHorizontalDepth();
|
||||
size_t vDepth = Session::getDVerticalDepth();
|
||||
size_t cDepth = Session::getDContactDepth();
|
||||
if (getFlags() & ToUpperRouting) {
|
||||
hDepth += 2;
|
||||
vDepth += 2;
|
||||
cDepth += 2;
|
||||
}
|
||||
const Layer* viaLayer = Session::getContactLayer( cDepth );
|
||||
|
||||
if (getConnexity().fields.globals == 2) {
|
||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
|
@ -466,20 +510,20 @@ namespace Anabatic {
|
|||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
if (south()) swapCornerContacts();
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical, vDepth );
|
||||
} else {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
if (west()) swapCornerContacts();
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal, hDepth );
|
||||
}
|
||||
} else { // fields.globals == 4.
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal );
|
||||
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical );
|
||||
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal, hDepth );
|
||||
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical , vDepth );
|
||||
}
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
|
@ -490,16 +534,24 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_2G()" << endl;
|
||||
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
size_t hDepth = Session::getDHorizontalDepth();
|
||||
size_t vDepth = Session::getDVerticalDepth();
|
||||
size_t cDepth = Session::getDContactDepth();
|
||||
if (getFlags() & ToUpperRouting) {
|
||||
hDepth += 2;
|
||||
vDepth += 2;
|
||||
cDepth += 2;
|
||||
}
|
||||
const Layer* viaLayer = Session::getContactLayer( cDepth );
|
||||
|
||||
if (east() and west()) {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical, vDepth );
|
||||
} else if (south() and north()) {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal, hDepth );
|
||||
} else {
|
||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
}
|
||||
|
@ -1568,7 +1620,7 @@ namespace Anabatic {
|
|||
biggestRp = getRoutingPads()[i];
|
||||
}
|
||||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
|
||||
if (east() and west() and not south() and not north()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, HBothAccess );
|
||||
|
@ -1580,6 +1632,7 @@ namespace Anabatic {
|
|||
if (west() and not south()) {
|
||||
setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) );
|
||||
} else if (not west() and south()) {
|
||||
cdebug_log(145,1) << "case: not west and south" << endl;
|
||||
setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
|
||||
} else if (west() and south()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
|
||||
|
@ -1590,6 +1643,7 @@ namespace Anabatic {
|
|||
if (east() and not north()) {
|
||||
setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) );
|
||||
} else if (not east() and north()) {
|
||||
cdebug_log(145,1) << "case: not east and north" << endl;
|
||||
setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
|
||||
} else if (east() and north()) {
|
||||
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
|
||||
|
@ -1605,6 +1659,7 @@ namespace Anabatic {
|
|||
bool NetBuilderHV::_do_1G_1M3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M3() [Optimised Configuration]" << endl;
|
||||
size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() );
|
||||
|
||||
uint64_t flags = (east() or west()) ? HAccess : NoFlags;
|
||||
flags |= (north()) ? DoTargetContact : NoFlags;
|
||||
|
@ -1622,6 +1677,13 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "_southWest: " << getSouthWestContact() << endl;
|
||||
cdebug_log(145,0) << "_northEast: " << getNorthEastContact() << endl;
|
||||
|
||||
if (not (east() or west())) {
|
||||
AutoContact* subContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer((rpDepth)) );
|
||||
AutoSegment::create( getSouthWestContact(), subContact, Flags::Horizontal, rpDepth+1 );
|
||||
setBothCornerContacts( subContact );
|
||||
}
|
||||
|
||||
#if THIS_IS_DISABLED
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
|
||||
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
||||
|
@ -1658,6 +1720,7 @@ namespace Anabatic {
|
|||
setBothCornerContacts( turn2 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
@ -1665,9 +1728,28 @@ namespace Anabatic {
|
|||
|
||||
bool NetBuilderHV::_do_xG_xM3 ()
|
||||
{
|
||||
size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() );
|
||||
if (getGCell()->getDensity(rpDepth) > 0.5)
|
||||
return _do_xG_xM3_upperRouting();
|
||||
return _do_xG_xM3_baseRouting();
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_xM3_baseRouting ()
|
||||
{
|
||||
size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() );
|
||||
size_t vDepth = rpDepth + 2;
|
||||
size_t hDepth = rpDepth + 1;
|
||||
const Layer* viaLayer = Session::getContactLayer( rpDepth );
|
||||
if (Session::getRoutingGauge()->isSuperPitched()) {
|
||||
viaLayer = Session::getContactLayer( 1 );
|
||||
vDepth = 2;
|
||||
hDepth = 1;
|
||||
}
|
||||
|
||||
cdebug_log(145,1) << getTypeName()
|
||||
<< "::_do_xG_" << (int)getConnexity().fields.M3
|
||||
<< "M3() [Managed Configuration]" << endl;
|
||||
<< "M3_baseRouting() [Managed Configuration]" << endl;
|
||||
cdebug_log(145,0) << "west:" << west() << endl;
|
||||
cdebug_log(145,0) << "east:" << east() << endl;
|
||||
cdebug_log(145,0) << "south:" << south() << endl;
|
||||
|
@ -1678,7 +1760,6 @@ namespace Anabatic {
|
|||
doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
|
||||
}
|
||||
|
||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||
AutoContact* unusedContact = NULL;
|
||||
Component* rp = getRoutingPads()[0];
|
||||
|
||||
|
@ -1691,18 +1772,18 @@ namespace Anabatic {
|
|||
cdebug_log(149,0) << "Misaligned South: _source:" << DbU::getValueString(getSourceContact()->getX())
|
||||
<< "_southWest:" << DbU::getValueString(getSouthWestContact()->getX()) << endl;
|
||||
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical , vDepth );
|
||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal, hDepth );
|
||||
setSouthWestContact( turn2 );
|
||||
}
|
||||
}
|
||||
} else if (west() and south()) {
|
||||
AutoContact* rpContact = NULL;
|
||||
doRp_AutoContacts( getGCell(), rp, rpContact, unusedContact, DoSourceContact );
|
||||
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical );
|
||||
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical, vDepth );
|
||||
}
|
||||
|
||||
rp = getRoutingPads()[getRoutingPads().size()-1];
|
||||
|
@ -1715,18 +1796,102 @@ namespace Anabatic {
|
|||
cdebug_log(149,0) << "Misaligned North: _source:" << DbU::getValueString(getSourceContact()->getX())
|
||||
<< "_southWest:" << DbU::getValueString(getNorthEastContact()->getX()) << endl;
|
||||
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
||||
AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical );
|
||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
|
||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical , vDepth );
|
||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal, hDepth );
|
||||
setNorthEastContact( turn2 );
|
||||
}
|
||||
}
|
||||
} else if (east() and north()) {
|
||||
AutoContact* rpContact = NULL;
|
||||
doRp_AutoContacts( getGCell(), rp, unusedContact, rpContact, DoTargetContact );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
||||
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical, vDepth );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHV::_do_xG_xM3_upperRouting ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName()
|
||||
<< "::_do_xG_" << (int)getConnexity().fields.M3
|
||||
<< "M3_upperRouting() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl;
|
||||
cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl;
|
||||
cdebug_log(145,0) << "north: " << north() << endl;
|
||||
cdebug_log(145,0) << "south: " << south() << endl;
|
||||
cdebug_log(145,0) << "east: " << east () << endl;
|
||||
cdebug_log(145,0) << "west: " << west () << endl;
|
||||
size_t rpDepth = Session::getLayerDepth( getRoutingPads()[0]->getLayer() );
|
||||
|
||||
sortRpByY( getRoutingPads(), NoFlags ); // increasing Y.
|
||||
for ( size_t i=1 ; i<getRoutingPads().size() ; i++ ) {
|
||||
doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
|
||||
}
|
||||
|
||||
if ((int)getConnexity().fields.M3 != 1) return false;
|
||||
|
||||
const Layer* viaLayer2 = Session::getContactLayer(rpDepth);
|
||||
|
||||
if (getConnexity().fields.globals == 2) {
|
||||
if (north() and south()) {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
|
||||
contact1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
|
||||
setNorthEastContact( contact1 );
|
||||
setSouthWestContact( contact2 );
|
||||
} else if (east() and west()) {
|
||||
AutoContact* contact1 = NULL;
|
||||
AutoContact* contact2 = NULL;
|
||||
doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags );
|
||||
setSouthWestContact( contact1 );
|
||||
doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags );
|
||||
setNorthEastContact( contact1 );
|
||||
} else {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
|
||||
|
||||
contact1 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Vertical, rpDepth+2 );
|
||||
setBothCornerContacts( contact1 );
|
||||
}
|
||||
} else if (getConnexity().fields.globals == 3) {
|
||||
if (not west() or not east()) {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
|
||||
AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact2, contact3, Flags::Vertical, rpDepth+2 );
|
||||
|
||||
setSouthWestContact( (east()) ? contact2 : contact3 );
|
||||
setNorthEastContact( (east()) ? contact3 : contact2 );
|
||||
} else {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags );
|
||||
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Vertical, rpDepth+2 );
|
||||
AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact2, contact3, Flags::Vertical, rpDepth+2 );
|
||||
|
||||
setSouthWestContact( (north()) ? contact2 : contact3 );
|
||||
setNorthEastContact( (north()) ? contact3 : contact2 );
|
||||
}
|
||||
} else {
|
||||
AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess );
|
||||
AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact1, contact2, Flags::Horizontal, rpDepth+1 );
|
||||
AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact2, contact3, Flags::Vertical, rpDepth+2 );
|
||||
AutoContact* contact4 = AutoContactVTee::create( getGCell(), getNet(), viaLayer2 );
|
||||
AutoSegment::create( contact2, contact4, Flags::Vertical, rpDepth+2 );
|
||||
|
||||
setSouthWestContact( contact3 );
|
||||
setNorthEastContact( contact4 );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
|
@ -1737,6 +1902,8 @@ namespace Anabatic {
|
|||
bool NetBuilderHV::_do_globalSegment ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
|
||||
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
|
||||
<< " getFlags():" << getFlags() << endl;
|
||||
|
||||
if (getSourceContact()) {
|
||||
AutoContact* targetContact
|
||||
|
@ -1744,7 +1911,16 @@ namespace Anabatic {
|
|||
? getNorthEastContact() : getSouthWestContact() ;
|
||||
if (not getFromHook()) cerr << "getFromHook() is NULL !" << endl;
|
||||
|
||||
Segment* baseSegment = static_cast<Segment*>( getFromHook()->getComponent() );
|
||||
Segment* baseSegment = static_cast<Segment*>( getFromHook()->getComponent() );
|
||||
if ( (getSourceFlags() | getFlags()) & ToUpperRouting) {
|
||||
cdebug_log(145,0) << "Moving up global" << endl;
|
||||
size_t gdepth = Session::getGHorizontalDepth();
|
||||
if (dynamic_cast<Vertical*>(baseSegment))
|
||||
gdepth = Session::getGVerticalDepth();
|
||||
baseSegment->setLayer( Session::getRoutingLayer( gdepth+2 ));
|
||||
baseSegment->setWidth( Session::getWireWidth( gdepth+2 ));
|
||||
}
|
||||
|
||||
AutoSegment* globalSegment = AutoSegment::create( getSourceContact()
|
||||
, targetContact
|
||||
, baseSegment
|
||||
|
|
|
@ -85,7 +85,6 @@ namespace Anabatic {
|
|||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
Flags direction = Session::getDirection ( rpDepth );
|
||||
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
|
||||
DbU::Unit gridPosition = 0;
|
||||
|
||||
getPositions( rp, sourcePosition, targetPosition );
|
||||
|
||||
|
@ -114,56 +113,8 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Quasi-punctual M1 terminal.
|
||||
if (flags & VSmall) {
|
||||
Box ab = rp->getCell()->getBoundingBox();
|
||||
RoutingLayerGauge* gaugeMetal3 = Session::getLayerGauge( 2 );
|
||||
DbU::Unit metal3axis = gaugeMetal3->getTrackPosition( ab.getYMin()
|
||||
, ab.getYMax()
|
||||
, sourcePosition.getY()
|
||||
, Constant::Nearest );
|
||||
DbU::Unit viaSideProtect = Session::getViaWidth((size_t)0);
|
||||
|
||||
AutoContact* sourceVia12 = AutoContactTerminal::create( sourceGCell
|
||||
, rp
|
||||
, Session::getContactLayer(0)
|
||||
, sourcePosition
|
||||
, viaSideProtect, viaSideProtect
|
||||
);
|
||||
AutoContact* targetVia12 = AutoContactTerminal::create( targetGCell
|
||||
, rp
|
||||
, Session::getContactLayer(0)
|
||||
, targetPosition
|
||||
, viaSideProtect, viaSideProtect
|
||||
);
|
||||
AutoContact* sourceVia23 = AutoContactTurn::create( sourceGCell, net, Session::getContactLayer(1) );
|
||||
AutoContact* targetVia23 = AutoContactTurn::create( targetGCell, net, Session::getContactLayer(1) );
|
||||
sourceVia23->setY( metal3axis );
|
||||
targetVia23->setY( metal3axis );
|
||||
sourceVia23->setX( sourcePosition.getX() );
|
||||
targetVia23->setX( targetPosition.getX() );
|
||||
|
||||
AutoSegment* segmentS = AutoSegment::create( sourceVia12, sourceVia23, Flags::Vertical );
|
||||
AutoSegment* segmentT = AutoSegment::create( targetVia12, targetVia23, Flags::Vertical );
|
||||
AutoSegment* segmentM = AutoSegment::create( sourceVia23, targetVia23, Flags::Horizontal );
|
||||
|
||||
sourceVia12->setFlags( CntFixed );
|
||||
sourceVia23->setFlags( CntFixed );
|
||||
targetVia12->setFlags( CntFixed );
|
||||
targetVia23->setFlags( CntFixed );
|
||||
segmentS->setFlags( AutoSegment::SegFixed );
|
||||
segmentT->setFlags( AutoSegment::SegFixed );
|
||||
segmentM->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
cdebug_log(145,0) << "Hard protect: " << rp << endl;
|
||||
cdebug_log(145,0) << "X:" << DbU::getValueString(sourcePosition.getX())
|
||||
<< " Metal3 Track Y:" << DbU::getValueString(metal3axis) << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Non-M1 terminal or punctual M1 protections.
|
||||
if ( (rpDepth != 0) or ((sourcePosition == targetPosition) and (gridPosition == 0)) ) {
|
||||
if ( (rpDepth != 0) or (sourcePosition == targetPosition) ) {
|
||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||
if (irp == getRpLookup().end()) {
|
||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
||||
|
@ -205,6 +156,10 @@ namespace Anabatic {
|
|||
);
|
||||
}
|
||||
|
||||
if ( (rpDepth > 0) and not Session::getRoutingGauge()->isSuperPitched() ) {
|
||||
rpLayer = Session::getContactLayer( rpDepth );
|
||||
}
|
||||
|
||||
if (not source and not target) {
|
||||
source = target = AutoContactTerminal::create( gcell
|
||||
, rp
|
||||
|
@ -223,28 +178,43 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
|
||||
|
||||
AutoContact* rpContactSource;
|
||||
AutoContact* rpContactTarget;
|
||||
AutoContact* rpContactSource = NULL;
|
||||
AutoContact* rpContactTarget = NULL;
|
||||
const Layer* rpLayer = rp->getLayer();
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
|
||||
flags |= checkRoutingPadSize( rp );
|
||||
|
||||
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
|
||||
|
||||
if (not (flags & (HAccess|HAccessEW))) {
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
||||
rpContactSource = subContact2;
|
||||
} else {
|
||||
if (flags & VSmall) {
|
||||
if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3).
|
||||
if (not (flags & (HAccess|HAccessEW))) {
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
|
||||
rpContactSource = subContact2;
|
||||
} else {
|
||||
if (flags & VSmall) {
|
||||
AutoContact* subContact1 = NULL;
|
||||
if (flags & HAccessEW)
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
else
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
||||
rpContactSource = subContact1;
|
||||
}
|
||||
}
|
||||
} else { // RP should be horizontal (M2).
|
||||
if (flags & (HAccess|HAccessEW)) {
|
||||
AutoContact* subContact1 = NULL;
|
||||
if (flags & HAccessEW)
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
else
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical, rpDepth+1 );
|
||||
rpContactSource = subContact1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,6 +215,7 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
|
||||
|
||||
_anabatic->disableCanonize();
|
||||
for ( Net* net : _netInvalidateds ) {
|
||||
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl;
|
||||
_anabatic->updateNetTopology ( net );
|
||||
|
@ -222,6 +223,7 @@ namespace Anabatic {
|
|||
_anabatic->_computeNetOptimals ( net );
|
||||
//_anabatic->_computeNetTerminals ( net );
|
||||
}
|
||||
_anabatic->enableCanonize();
|
||||
_canonize ();
|
||||
|
||||
AutoSegment* segment = NULL;
|
||||
|
|
|
@ -204,6 +204,7 @@ namespace Anabatic {
|
|||
public:
|
||||
static AnabaticEngine* create ( Cell* );
|
||||
static AnabaticEngine* get ( const Cell* );
|
||||
inline bool isCanonizeDisabled () const;
|
||||
static const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual Configuration* getConfiguration ();
|
||||
|
@ -227,6 +228,8 @@ namespace Anabatic {
|
|||
virtual void openSession ();
|
||||
inline void setState ( EngineState state );
|
||||
inline void setDensityMode ( uint64_t );
|
||||
inline void disableCanonize ();
|
||||
inline void enableCanonize ();
|
||||
inline void addOv ( Edge* );
|
||||
inline void removeOv ( Edge* );
|
||||
inline const NetDatas& getNetDatas () const;
|
||||
|
@ -380,6 +383,7 @@ namespace Anabatic {
|
|||
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
|
||||
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
|
||||
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
|
||||
inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; }
|
||||
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
|
||||
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); }
|
||||
|
@ -399,6 +403,8 @@ namespace Anabatic {
|
|||
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
|
||||
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
|
||||
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
|
||||
inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; }
|
||||
inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); }
|
||||
|
||||
inline void AnabaticEngine::_add ( GCell* gcell )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace Anabatic {
|
|||
static const BaseFlags DestroyGCell ; // = (1 << 7);
|
||||
static const BaseFlags DestroyBaseContact ; // = (1 << 8);
|
||||
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
|
||||
static const BaseFlags DisableCanonize ; // = (1 << 10);
|
||||
// Flags for NetDatas objects states only.
|
||||
static const BaseFlags GlobalFixed ; // = (1 << 5);
|
||||
static const BaseFlags GlobalEstimated ; // = (1 << 6);
|
||||
|
|
|
@ -259,6 +259,7 @@ namespace Anabatic {
|
|||
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
|
||||
void setType ( Flags );
|
||||
inline void setSatProcessed ( size_t depth );
|
||||
void postGlobalAnnotate ();
|
||||
void addBlockage ( size_t depth, DbU::Unit );
|
||||
inline void addHSegment ( AutoSegment* );
|
||||
inline void addVSegment ( AutoSegment* );
|
||||
|
|
|
@ -47,31 +47,39 @@ namespace Anabatic {
|
|||
|
||||
class ForkStack {
|
||||
public:
|
||||
inline void push ( Hook* from, AutoContact* contact );
|
||||
inline void push ( Hook* from, AutoContact* contact, uint64_t flags );
|
||||
inline void pop ();
|
||||
inline Hook* getFrom () const;
|
||||
inline AutoContact* getContact () const;
|
||||
inline uint64_t getFlags () const;
|
||||
inline void setFlags ( uint64_t );
|
||||
private:
|
||||
struct Element {
|
||||
Hook* _from;
|
||||
AutoContact* _contact;
|
||||
inline Element ( Hook* from, AutoContact* contact );
|
||||
uint64_t _flags;
|
||||
inline Element ( Hook* from, AutoContact* contact, uint64_t flags );
|
||||
};
|
||||
private:
|
||||
list<Element> _stack;
|
||||
};
|
||||
|
||||
|
||||
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact ) : _from(from), _contact(contact) {}
|
||||
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact, uint64_t flags ) : _from(from), _contact(contact), _flags(flags) {}
|
||||
inline void ForkStack::pop () { if (not _stack.empty()) _stack.pop_back(); }
|
||||
inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; }
|
||||
inline AutoContact* ForkStack::getContact () const { return _stack.empty() ? NULL : _stack.back()._contact; }
|
||||
inline uint64_t ForkStack::getFlags () const { return _stack.empty() ? 0 : _stack.back()._flags; }
|
||||
inline void ForkStack::setFlags ( uint64_t flags ) { if (not _stack.empty()) _stack.back()._flags |= flags; }
|
||||
|
||||
|
||||
inline void ForkStack::push ( Hook* from, AutoContact* contact )
|
||||
inline void ForkStack::push ( Hook* from, AutoContact* contact, uint64_t flags )
|
||||
{
|
||||
cdebug_log(145,0) << " Stacking " << from << " + " << contact << endl;
|
||||
_stack.push_back( Element(from,contact) );
|
||||
cdebug_log(145,0) << " Stacking: " << endl;
|
||||
cdebug_log(145,0) << " + " << from << endl;
|
||||
cdebug_log(145,0) << " + " << contact << endl;
|
||||
cdebug_log(145,0) << " + " << flags << endl;
|
||||
_stack.push_back( Element(from,contact,flags) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,6 +107,7 @@ namespace Anabatic {
|
|||
, Middle = (1 << 16)
|
||||
, UseNonPref = (1 << 17)
|
||||
, NoProtect = (1 << 18)
|
||||
, ToUpperRouting = (1 << 19)
|
||||
, HBothAccess = HAccess|HAccessEW
|
||||
, SouthWest = SouthBound|WestBound
|
||||
, NorthEast = NorthBound|EastBound
|
||||
|
@ -149,13 +158,15 @@ namespace Anabatic {
|
|||
virtual ~NetBuilder ();
|
||||
void clear ();
|
||||
inline bool isTwoMetals () const;
|
||||
inline bool isUpperMetalRp () const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline unsigned int getDegree () const;
|
||||
inline void setDegree ( unsigned int degree );
|
||||
void fixSegments ();
|
||||
NetBuilder& setStartHook ( AnabaticEngine*
|
||||
, Hook* fromHook
|
||||
, AutoContact* sourceContact=NULL );
|
||||
, AutoContact* sourceContact=NULL
|
||||
, uint64_t sourceFlags=0 );
|
||||
void construct ();
|
||||
inline unsigned int getStateG () const;
|
||||
inline UConnexity getConnexity () const;
|
||||
|
@ -169,6 +180,8 @@ namespace Anabatic {
|
|||
inline AutoContact* getNorthEastContact () const;
|
||||
inline AutoContact*& getNorthEastContact ();
|
||||
inline Hook* getFromHook () const;
|
||||
inline uint64_t getSourceFlags () const;
|
||||
inline uint64_t getFlags () const;
|
||||
inline ForkStack& getForks ();
|
||||
inline vector<RoutingPad*>& getRoutingPads ();
|
||||
inline map<Component*,AutoSegment*>& getRpLookup ();
|
||||
|
@ -187,6 +200,7 @@ namespace Anabatic {
|
|||
inline void clearSouths ();
|
||||
inline void clearEasts ();
|
||||
inline void clearWests ();
|
||||
inline void setFlags ( uint64_t );
|
||||
inline void setFromHook ( Hook* );
|
||||
inline void setSouthWestContact ( AutoContact* );
|
||||
inline void setNorthEastContact ( AutoContact* );
|
||||
|
@ -194,6 +208,7 @@ namespace Anabatic {
|
|||
inline void swapCornerContacts ();
|
||||
inline void addToFixSegments ( AutoSegment* );
|
||||
bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 );
|
||||
bool isInsideBlockage ( GCell*, Component* ) const;
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ) = 0;
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ) = 0;
|
||||
virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags );
|
||||
|
@ -372,9 +387,8 @@ namespace Anabatic {
|
|||
vector<AutoSegment*> _toFixSegments;
|
||||
unsigned int _degree;
|
||||
bool _isTwoMetals;
|
||||
|
||||
// Sort classes.
|
||||
public:
|
||||
uint64_t _sourceFlags;
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
|
||||
|
@ -394,6 +408,8 @@ namespace Anabatic {
|
|||
inline AutoContact* NetBuilder::getNorthEastContact () const { return _northEastContact; }
|
||||
inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; }
|
||||
inline Hook* NetBuilder::getFromHook () const { return _fromHook; }
|
||||
inline uint64_t NetBuilder::getSourceFlags () const { return _sourceFlags; }
|
||||
inline uint64_t NetBuilder::getFlags () const { return _flags; }
|
||||
inline unsigned int NetBuilder::getTopology () const { return _topology; }
|
||||
inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; }
|
||||
inline map<Component*,AutoSegment*>& NetBuilder::getRpLookup () { return _routingPadAutoSegments; }
|
||||
|
@ -403,6 +419,7 @@ namespace Anabatic {
|
|||
inline Hook* NetBuilder::south ( size_t i ) const { return (i<_souths.size()) ? _souths[i] : NULL; }
|
||||
inline Hook* NetBuilder::east ( size_t i ) const { return (i<_easts .size()) ? _easts [i] : NULL; }
|
||||
inline Hook* NetBuilder::west ( size_t i ) const { return (i<_wests .size()) ? _wests [i] : NULL; }
|
||||
inline void NetBuilder::setFlags ( uint64_t flags ) { _flags |= flags; }
|
||||
inline void NetBuilder::setDegree ( unsigned int degree ) { _degree = degree; }
|
||||
inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; }
|
||||
inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; }
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderHV.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef ANABATIC_NET_BUILDER_HV_H
|
||||
#define ANABATIC_NET_BUILDER_HV_H
|
||||
|
||||
#pragma once
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -28,44 +26,44 @@ namespace Anabatic {
|
|||
|
||||
class NetBuilderHV : public NetBuilder {
|
||||
public:
|
||||
NetBuilderHV ();
|
||||
virtual ~NetBuilderHV ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
||||
private:
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual bool _do_1G_1PinM3 ();
|
||||
virtual bool _do_xG_1PinM3 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
virtual bool _do_2G_xM1_1PinM2 ();
|
||||
virtual bool _do_1G_1M1_1PinM3 ();
|
||||
virtual bool _do_2G_xM1_1PinM3 ();
|
||||
virtual bool _do_3G_xM1_1PinM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
NetBuilderHV ();
|
||||
virtual ~NetBuilderHV ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
||||
private:
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual bool _do_1G_1PinM3 ();
|
||||
virtual bool _do_xG_1PinM3 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
bool _do_xG_xM3_baseRouting ();
|
||||
bool _do_xG_xM3_upperRouting ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
virtual bool _do_2G_xM1_1PinM2 ();
|
||||
virtual bool _do_1G_1M1_1PinM3 ();
|
||||
virtual bool _do_2G_xM1_1PinM3 ();
|
||||
virtual bool _do_3G_xM1_1PinM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
};
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_HV_H
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderVH.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef ANABATIC_NET_BUILDER_VH_H
|
||||
#define ANABATIC_NET_BUILDER_VH_H
|
||||
|
||||
#pragma once
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -50,5 +48,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_VH_H
|
||||
|
|
|
@ -825,7 +825,7 @@ namespace CRL {
|
|||
|
||||
CellGauge* AllianceFramework::matchCellGauge ( DbU::Unit width, DbU::Unit height ) const
|
||||
{
|
||||
for ( const auto item : _cellGauges ) {
|
||||
for ( const auto& item : _cellGauges ) {
|
||||
CellGauge* cg = item.second;
|
||||
DbU::Unit hcount = width / cg->getSliceStep ();
|
||||
DbU::Unit hremains = width % cg->getSliceStep ();
|
||||
|
@ -842,7 +842,7 @@ namespace CRL {
|
|||
|
||||
CellGauge* AllianceFramework::matchCellGaugeByHeight ( DbU::Unit height ) const
|
||||
{
|
||||
for ( const auto item : _cellGauges ) {
|
||||
for ( const auto& item : _cellGauges ) {
|
||||
CellGauge* cg = item.second;
|
||||
DbU::Unit vcount = height / cg->getSliceHeight();
|
||||
DbU::Unit vremains = height % cg->getSliceHeight();
|
||||
|
|
|
@ -56,20 +56,22 @@ namespace CRL {
|
|||
|
||||
|
||||
RoutingGauge::RoutingGauge ( const char* name )
|
||||
: _name (name)
|
||||
, _layerGauges()
|
||||
, _viaLayers ()
|
||||
, _technology (DataBase::getDB()->getTechnology())
|
||||
, _isSymbolic (true)
|
||||
: _name (name)
|
||||
, _layerGauges ()
|
||||
, _viaLayers ()
|
||||
, _technology (DataBase::getDB()->getTechnology())
|
||||
, _isSymbolic (true)
|
||||
, _isSuperPitched(true)
|
||||
{ }
|
||||
|
||||
|
||||
RoutingGauge::RoutingGauge ( const RoutingGauge& gauge )
|
||||
: _name (gauge._name)
|
||||
, _layerGauges()
|
||||
, _viaLayers ()
|
||||
, _technology (gauge._technology)
|
||||
, _isSymbolic (gauge._isSymbolic)
|
||||
: _name (gauge._name)
|
||||
, _layerGauges ()
|
||||
, _viaLayers ()
|
||||
, _technology (gauge._technology)
|
||||
, _isSymbolic (gauge._isSymbolic)
|
||||
, _isSuperPitched(gauge._isSuperPitched)
|
||||
{
|
||||
// Make a deep copy of the map.
|
||||
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ ) {
|
||||
|
@ -304,6 +306,12 @@ namespace CRL {
|
|||
}
|
||||
_viaLayers.push_back( viaLayer );
|
||||
}
|
||||
|
||||
if ((gaugeSize > 3) and _isSuperPitched) {
|
||||
float r = ((float)layerGauge->getPitch() / (float)_layerGauges[gaugeSize-3]->getPitch());
|
||||
if (fabsf(roundf(r) - r) > 0.00001f)
|
||||
_isSuperPitched = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Vhdl {
|
|||
Bit* bit = BitExtension::get( net );
|
||||
if (bit) return bit;
|
||||
|
||||
cerr << Error( "PortMap::_lookup() VHDL extension missing on \"%s\"."
|
||||
cerr << Error( "PortMap::_lookup() VHDL extension missing on \"%s\".\n"
|
||||
" In cell \"%s\"."
|
||||
, getString(net).c_str()
|
||||
, getString(net->getCell()->getName()).c_str()
|
||||
|
|
|
@ -854,12 +854,12 @@ association_element
|
|||
<< " Port map assignment discrepency "
|
||||
<< "instance:" << Vst::states->_instanceNets.size()
|
||||
<< " vs. model:" << Vst::states->_masterNets.size();
|
||||
message << "\nModel:";
|
||||
message << "\nModel \"" << Vst::states->_instance->getMasterCell()->getName() << "\":";
|
||||
for ( Net* net : Vst::states->_masterNets )
|
||||
message << " \"" << net->getName() << "\"";
|
||||
message << "\nInstance:";
|
||||
message << "\n* \"" << net->getName() << "\"";
|
||||
message << "\nInstance " << Vst::states->_instance->getName() << "\":";
|
||||
for ( Net* net : Vst::states->_instanceNets )
|
||||
message << " \"" << net->getName() << "\"";
|
||||
message << "\n* \"" << net->getName() << "\"";
|
||||
throw Error( message.str() );
|
||||
}
|
||||
|
||||
|
|
|
@ -280,13 +280,15 @@ namespace {
|
|||
void connectSubckts ();
|
||||
Net* mergeNet ( string name, bool isExternal, unsigned int );
|
||||
Net* mergeAlias ( string name1, string name2 );
|
||||
Net* newDummyNet ();
|
||||
private:
|
||||
Cell* _cell;
|
||||
Subckts _subckts;
|
||||
size_t _depth;
|
||||
size_t _supplyCount;
|
||||
Instance* _oneInstance;
|
||||
Instance* _zeroInstance;
|
||||
Cell* _cell;
|
||||
Subckts _subckts;
|
||||
size_t _depth;
|
||||
size_t _supplyCount;
|
||||
Instance* _oneInstance;
|
||||
Instance* _zeroInstance;
|
||||
vector<Net*> _dummyOutputs;
|
||||
};
|
||||
|
||||
|
||||
|
@ -482,6 +484,7 @@ namespace {
|
|||
, _supplyCount (0)
|
||||
, _oneInstance (NULL)
|
||||
, _zeroInstance(NULL)
|
||||
, _dummyOutputs()
|
||||
{
|
||||
if (not _staticInit) staticInit();
|
||||
|
||||
|
@ -546,6 +549,15 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
Net* Model::newDummyNet ()
|
||||
{
|
||||
ostringstream name;
|
||||
name << "blif_dummy_output_" << _dummyOutputs.size();
|
||||
_dummyOutputs.push_back( Net::create( _cell, name.str().c_str() ) );
|
||||
return _dummyOutputs.back();
|
||||
}
|
||||
|
||||
|
||||
Net* Model::mergeNet ( string name, bool isExternal, unsigned int direction )
|
||||
{
|
||||
bool isClock = AllianceFramework::get()->isCLOCK( name );
|
||||
|
@ -766,6 +778,29 @@ namespace {
|
|||
if (not message.str().empty()) cerr << Warning( message.str() ) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
for ( Plug* plug : instance->getPlugs()) {
|
||||
if (plug->getMasterNet()->isSupply()) continue;
|
||||
Net* connectedNet = plug->getNet();
|
||||
if (not connectedNet) {
|
||||
if (plug->getMasterNet()->getDirection() & Net::Direction::DirIn) {
|
||||
ostringstream message;
|
||||
message << "In " << instance << "\n "
|
||||
<< "*input* Terminal \"" << plug->getMasterNet()->getName()
|
||||
<< "\" is *not* connected.";
|
||||
cerr << Error( message.str() ) << endl;
|
||||
} else {
|
||||
Net* dummyNet = newDummyNet();
|
||||
plug->setNet( dummyNet );
|
||||
ostringstream message;
|
||||
message << "In " << instance << "\n "
|
||||
<< "*output* Terminal \"" << plug->getMasterNet()->getName()
|
||||
<< "\" is *not* connected, generating dummy net \""
|
||||
<< dummyNet->getName() << "\".";
|
||||
cerr << Warning( message.str() ) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef CRL_ROUTING_GAUGE_H
|
||||
#define CRL_ROUTING_GAUGE_H
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "hurricane/Name.h"
|
||||
|
@ -56,6 +54,7 @@ namespace CRL {
|
|||
// Predicates.
|
||||
inline bool isSymbolic () const;
|
||||
inline bool isTwoMetals () const;
|
||||
inline bool isSuperPitched () const;
|
||||
inline bool isHV () const;
|
||||
inline bool isVH () const;
|
||||
inline bool hasPowerSupply () const;
|
||||
|
@ -109,6 +108,7 @@ namespace CRL {
|
|||
vector<Layer*> _viaLayers;
|
||||
Technology* _technology;
|
||||
bool _isSymbolic;
|
||||
bool _isSuperPitched;
|
||||
|
||||
// Internal - Constructors & Destructors.
|
||||
RoutingGauge ( const char* name );
|
||||
|
@ -120,6 +120,7 @@ namespace CRL {
|
|||
|
||||
|
||||
inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; }
|
||||
inline bool RoutingGauge::isSuperPitched () const { return _isSuperPitched; }
|
||||
inline bool RoutingGauge::isTwoMetals () const { return (getDepth() < 3); }
|
||||
inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
|
||||
inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
|
||||
|
@ -155,5 +156,3 @@ namespace CRL {
|
|||
} // CRL namespace.
|
||||
|
||||
INSPECTOR_P_SUPPORT(CRL::RoutingGauge);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -88,15 +88,16 @@ namespace CRL {
|
|||
if ( vhdlName.empty() and (isdigit(translated)) )
|
||||
vhdlName += 'n';
|
||||
|
||||
if (translated == '\\') translated = '_';
|
||||
if (translated == '/' ) translated = '_';
|
||||
if (translated == '.' ) translated = '_';
|
||||
if (translated == '%' ) translated = '_';
|
||||
if (translated == '$' ) translated = '_';
|
||||
if (translated == '?' ) translated = '_';
|
||||
if (translated == ':' ) translated = '_';
|
||||
if (translated == '[' ) translated = leftPar;
|
||||
if (translated == ']' ) translated = rightPar;
|
||||
if (translated == '\\' ) translated = '_';
|
||||
if (translated == '/' ) translated = '_';
|
||||
if (translated == '.' ) translated = '_';
|
||||
if (translated == '%' ) translated = '_';
|
||||
if (translated == '$' ) translated = '_';
|
||||
if (translated == '?' ) translated = '_';
|
||||
if (translated == '\'' ) translated = '_';
|
||||
if (translated == ':' ) translated = '_';
|
||||
if (translated == '[' ) translated = leftPar;
|
||||
if (translated == ']' ) translated = rightPar;
|
||||
|
||||
if (translated == '_') {
|
||||
if (vhdlName.empty() ) continue;
|
||||
|
|
|
@ -504,6 +504,7 @@ extern "C" {
|
|||
GetNameMethod(RoutingGauge,rg)
|
||||
accessorVectorFromVoid(getLayerGauges,PyRoutingGauge,RoutingGauge,RoutingLayerGauge)
|
||||
DirectGetBoolAttribute(PyRoutingGauge_isSymbolic ,isSymbolic ,PyRoutingGauge,RoutingGauge)
|
||||
DirectGetBoolAttribute(PyRoutingGauge_isSuperPitched,isSuperPitched,PyRoutingGauge,RoutingGauge)
|
||||
DirectSetBoolAttribute(PyRoutingGauge_setSymbolic ,setSymbolic ,PyRoutingGauge,RoutingGauge)
|
||||
DirectGetBoolAttribute(PyRoutingGauge_isHV ,isHV ,PyRoutingGauge,RoutingGauge)
|
||||
DirectGetBoolAttribute(PyRoutingGauge_isVH ,isVH ,PyRoutingGauge,RoutingGauge)
|
||||
|
@ -518,6 +519,8 @@ extern "C" {
|
|||
, "Create a new RoutingGauge." }
|
||||
, { "isSymbolic" , (PyCFunction)PyRoutingGauge_isSymbolic , METH_NOARGS
|
||||
, "The RoutingGauge is for symbolic technology." }
|
||||
, { "isSuperPitched" , (PyCFunction)PyRoutingGauge_isSuperPitched , METH_NOARGS
|
||||
, "The RoutingGauge is super-pitched." }
|
||||
, { "isHV" , (PyCFunction)PyRoutingGauge_isHV , METH_NOARGS
|
||||
, "The first routing layer (metal2) is horizontal." }
|
||||
, { "isVH" , (PyCFunction)PyRoutingGauge_isVH , METH_NOARGS
|
||||
|
|
|
@ -673,7 +673,9 @@ class Block ( object ):
|
|||
self.initEtesian()
|
||||
if self.conf.placeArea:
|
||||
self.etesian.setPlaceArea( self.conf.placeArea )
|
||||
if self.conf.useHFNS: self.etesian.doHFNS()
|
||||
if self.conf.useHFNS:
|
||||
self.etesian.doHFNS()
|
||||
Breakpoint.stop( 100, 'HFNS (Etesian) done.' )
|
||||
self.etesian.place()
|
||||
Breakpoint.stop( 100, 'Placement done.' )
|
||||
self.etesian.clearColoquinte()
|
||||
|
|
|
@ -1186,7 +1186,12 @@ class IoPin ( object ):
|
|||
self.stem = stem
|
||||
self.upos = upos
|
||||
self.ustep = ustep
|
||||
self.count = count
|
||||
if isinstance(count,int):
|
||||
self.count = count
|
||||
self.indexes = range(self.count)
|
||||
else:
|
||||
self.count = len(count)
|
||||
self.indexes = count
|
||||
if self.upos == 0 and not (self.flags & IoPin.A_MASK):
|
||||
raise ErrorMessage( 1, [ 'IoPin.__init__(): "upos" parameter cannot be zero, corners are forbidden.'
|
||||
, 'For net "{}"'.format(stem) ] )
|
||||
|
@ -1194,12 +1199,6 @@ class IoPin ( object ):
|
|||
raise ErrorMessage( 1, [ 'IoPin.__init__(): "ustep" parameter cannot be zero when "count" more than 1.'
|
||||
, 'For net "{}"'.format(stem) ] )
|
||||
|
||||
@property
|
||||
def indexes ( self ):
|
||||
if isinstance(self.count,int):
|
||||
return range(self.count)
|
||||
return self.count
|
||||
|
||||
# def place ( self, block ):
|
||||
# """
|
||||
# Performs the actual creation of the Pin. Should be called prior to any
|
||||
|
|
|
@ -115,8 +115,9 @@ class HTree ( object ):
|
|||
left1X = gaugeConf.getNearestVerticalTrack( tl1Contact.getX(), 0, 0 )
|
||||
left1Y = gaugeConf.getStackY( contact, GaugeConf.DeepDepth )
|
||||
dxLeft = contact.getX() - gaugeConf.getStackX( contact, GaugeConf.DeepDepth )
|
||||
gaugeConf.setStackPosition( tl1Contact, left1X, left1Y )
|
||||
gaugeConf.setStackPosition( tl2Contact, x , left1Y )
|
||||
gaugeConf.expandMinArea( tl2Contact )
|
||||
gaugeConf.setStackPosition( tl1Contact, left1X , left1Y )
|
||||
#gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth|GaugeConf.SourceExtend )
|
||||
gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth, dxLeft )
|
||||
gaugeConf.createVertical ( contact , tl2Contact, x, 0 )
|
||||
|
|
|
@ -144,9 +144,9 @@ class Chip ( Block ):
|
|||
self.conf.refresh()
|
||||
|
||||
def doPnR ( self ):
|
||||
super(Chip,self).doPnR()
|
||||
status = super(Chip,self).doPnR()
|
||||
self.conf.refresh( self.conf.chip )
|
||||
return self.conf.validated
|
||||
return self.conf.validated and status
|
||||
|
||||
def save ( self, flags=0 ):
|
||||
if not self.conf.validated:
|
||||
|
|
|
@ -29,6 +29,9 @@ except Exception as e:
|
|||
sys.exit(2)
|
||||
|
||||
|
||||
saveds = set()
|
||||
|
||||
|
||||
def rsave ( cell, views=CRL.Catalog.State.Physical, depth=0, enableSpice=False ):
|
||||
"""
|
||||
Write back layout to disk if everything has gone fine.
|
||||
|
@ -39,6 +42,12 @@ def rsave ( cell, views=CRL.Catalog.State.Physical, depth=0, enableSpice=False )
|
|||
of abutment box for placement, the netlist view must also
|
||||
be saved.
|
||||
"""
|
||||
global saveds
|
||||
|
||||
if depth == 0: saveds.clear()
|
||||
if cell in saveds: return
|
||||
saveds.add( cell )
|
||||
|
||||
framework = CRL.AllianceFramework.get()
|
||||
if depth == 0: print( ' o Recursive Save-Cell.' )
|
||||
if cell.isUniquified(): views |= CRL.Catalog.State.Logical
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace Etesian {
|
|||
using Hurricane::tab;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::Path;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::DataBase;
|
||||
|
@ -249,6 +250,7 @@ namespace Etesian {
|
|||
|
||||
void Cluster::splitNet ()
|
||||
{
|
||||
cdebug_log(123,0) << "Cluster::splitNet()" << endl;
|
||||
createOutput();
|
||||
for ( Cluster* cluster : _clusters ) {
|
||||
cluster->createInput( _driverNet );
|
||||
|
@ -291,10 +293,10 @@ namespace Etesian {
|
|||
virtual void splitNet ();
|
||||
void rpartition ();
|
||||
uint32_t build ();
|
||||
bool rcleanupNet ( Net* );
|
||||
string _getTypeName () const;
|
||||
private:
|
||||
SubNetNames _subNetNames;
|
||||
bool _isDeepNet;
|
||||
Net* _rootNet;
|
||||
RoutingPad* _rpDriver;
|
||||
vector< vector<Cluster*> > _clustersStack;
|
||||
|
@ -304,7 +306,6 @@ namespace Etesian {
|
|||
BufferTree::BufferTree ( EtesianEngine* etesian, Net* rootNet )
|
||||
: Cluster(etesian)
|
||||
, _subNetNames ()
|
||||
, _isDeepNet (true)
|
||||
, _rootNet (rootNet)
|
||||
, _rpDriver (NULL)
|
||||
, _clustersStack()
|
||||
|
@ -331,14 +332,18 @@ namespace Etesian {
|
|||
|
||||
void BufferTree::splitNet ()
|
||||
{
|
||||
cdebug_log(123,0) << "BufferTree::splitNet()" << endl;
|
||||
if (not _rpDriver)
|
||||
throw Error( "BufferTree::splitNet(): Missing driver on %s.", getString(_rootNet).c_str() );
|
||||
|
||||
Net* origDriver = _rootNet;
|
||||
|
||||
Cluster::splitNet();
|
||||
if (_isDeepNet) {
|
||||
if (_rootNet->isDeepNet()) {
|
||||
Cell* topCell = getEtesian()->getCell();
|
||||
Name topNetName = _rootNet->getName();
|
||||
Occurrence driverRpOcc = _rpDriver->getPlugOccurrence();
|
||||
origDriver = dynamic_cast<Net*>( static_cast<DeepNet*>( _rootNet )->getRootNetOccurrence().getEntity() );
|
||||
_rootNet->destroy();
|
||||
_rootNet = Net::create( topCell, topNetName );
|
||||
Net* deepDriverNet = raddTransNet( _rootNet, driverRpOcc.getPath(), AS_DRIVER );
|
||||
|
@ -346,6 +351,7 @@ namespace Etesian {
|
|||
RoutingPad::create( _rootNet, driverRpOcc, RoutingPad::BiggestArea );
|
||||
}
|
||||
createInput( _rootNet );
|
||||
rcleanupNet( origDriver );
|
||||
}
|
||||
|
||||
|
||||
|
@ -361,16 +367,15 @@ namespace Etesian {
|
|||
RoutingPad* rpPin = NULL;
|
||||
for ( RoutingPad* rp : _rootNet->getRoutingPads() ) {
|
||||
Occurrence rpOccurrence = rp->getPlugOccurrence();
|
||||
if (rpOccurrence.getPath().isEmpty())
|
||||
_isDeepNet = false;
|
||||
Pin* pin = dynamic_cast<Pin* >( rpOccurrence.getEntity() );
|
||||
if (pin) {
|
||||
if (not rpPin) {
|
||||
if (dynamic_cast<Pin* >( rpOccurrence.getEntity() )) {
|
||||
cdebug_log(123,0) << "pin: " << rp << endl;
|
||||
rpPin = rp;
|
||||
}
|
||||
}
|
||||
cdebug_log(123,0) << "Excluded: " << pin << endl;
|
||||
cdebug_log(123,0) << "Excluded second pin: " << pin << endl;
|
||||
continue;
|
||||
}
|
||||
Plug* rpPlug = dynamic_cast<Plug*>( rpOccurrence.getEntity() );
|
||||
|
@ -383,6 +388,7 @@ namespace Etesian {
|
|||
cdebug_log(123,0) << "merge: " << _clustersStack[0].back()->getSize() << " " << rp << endl;
|
||||
_clustersStack[0].back()->merge( rp );
|
||||
} else {
|
||||
cdebug_log(123,0) << "driver: " << rp << endl;
|
||||
_rpDriver = rp;
|
||||
}
|
||||
}
|
||||
|
@ -432,6 +438,8 @@ namespace Etesian {
|
|||
|
||||
uint32_t BufferTree::build ()
|
||||
{
|
||||
DebugSession::open( _rootNet, 120, 130 );
|
||||
cdebug_log(123,1) << "BufferTree::build() " << _rootNet << endl;
|
||||
uint32_t bufferCount = 0;
|
||||
rpartition();
|
||||
for ( vector<Cluster*>& clusters : _clustersStack ) {
|
||||
|
@ -440,9 +448,29 @@ namespace Etesian {
|
|||
++bufferCount;
|
||||
}
|
||||
}
|
||||
cdebug_tabw(123,-1);
|
||||
DebugSession::close();
|
||||
return bufferCount;
|
||||
}
|
||||
|
||||
|
||||
bool BufferTree::rcleanupNet ( Net* net )
|
||||
{
|
||||
if (net->getCell()->isTerminalNetlist() or net->getCell()->isTerminal())
|
||||
return false;
|
||||
vector<Plug*> plugs;
|
||||
for ( Plug* plug : net->getPlugs() ) plugs.push_back( plug );
|
||||
for ( Plug* plug : plugs ) {
|
||||
rcleanupNet( plug->getMasterNet() );
|
||||
}
|
||||
if (net->getPlugs().getFirst() == nullptr) {
|
||||
cdebug_log(123,0) << "BufferTree::rcleanupNet() " << net << " of " << net->getCell() << endl;
|
||||
net->destroy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
string BufferTree::_getTypeName () const
|
||||
{ return "BufferTree"; }
|
||||
|
@ -484,6 +512,7 @@ namespace Etesian {
|
|||
}
|
||||
}
|
||||
|
||||
//DebugSession::open( 120, 130 );
|
||||
UpdateSession::open();
|
||||
Go::disableAutoMaterialization();
|
||||
_bufferCount = 0;
|
||||
|
@ -508,6 +537,7 @@ namespace Etesian {
|
|||
// }
|
||||
Go::enableAutoMaterialization();
|
||||
UpdateSession::close();
|
||||
//DebugSession::close();
|
||||
|
||||
stopMeasures();
|
||||
printMeasures();
|
||||
|
|
|
@ -42,11 +42,11 @@ extern "C" {
|
|||
// +=================================================================+
|
||||
|
||||
|
||||
static PyObject* PyLayoutGenerator_getVerboseLevel ( PyObject* )
|
||||
static PyObject* PyLayoutGenerator_getVerboseLevel ( PyLayoutGenerator* )
|
||||
{ return Py_BuildValue( "i", LayoutGenerator::getVerboseLevel() ); }
|
||||
|
||||
|
||||
static PyObject* PyLayoutGenerator_setVerboseLevel ( PyObject*, PyObject* args )
|
||||
static PyObject* PyLayoutGenerator_setVerboseLevel ( PyLayoutGenerator*, PyObject* args )
|
||||
{
|
||||
int verboseLevel = 0;
|
||||
if (PyArg_ParseTuple( args, "i:LayoutGenerator.setVerboseLevel", &verboseLevel )) {
|
||||
|
@ -287,8 +287,8 @@ extern "C" {
|
|||
|
||||
|
||||
PyMethodDef PyLayoutGenerator_Methods[] =
|
||||
{ { "getVerboseLevel" , (PyCFunction)PyLayoutGenerator_getVerboseLevel , METH_NOARGS|METH_STATIC, "Return the verbosity level." }
|
||||
, { "setVerboseLevel" , (PyCFunction)PyLayoutGenerator_setVerboseLevel , METH_STATIC, "Sets the verbosity level." }
|
||||
{ { "getVerboseLevel" , (PyCFunction)PyLayoutGenerator_getVerboseLevel , METH_NOARGS|METH_CLASS, "Return the verbosity level." }
|
||||
, { "setVerboseLevel" , (PyCFunction)PyLayoutGenerator_setVerboseLevel , METH_CLASS, "Sets the verbosity level." }
|
||||
, { "getDevice" , (PyCFunction)PyLayoutGenerator_getDevice , METH_NOARGS , "Return the Device currently loaded." }
|
||||
, { "getNumberTransistor", (PyCFunction)PyLayoutGenerator_getNumberTransistor, METH_NOARGS , "Return how many real transistors (fingers) are useds." }
|
||||
, { "getNumberStack" , (PyCFunction)PyLayoutGenerator_getNumberStack , METH_NOARGS , "Return how many transistor stacks are useds." }
|
||||
|
|
|
@ -287,13 +287,13 @@ void Contact::translate(const DbU::Unit& dx, const DbU::Unit& dy)
|
|||
void Contact::setLayer(const Layer* layer)
|
||||
// ***************************************
|
||||
{
|
||||
if (!layer)
|
||||
throw Error("Can't set layer : null layer");
|
||||
if (not layer)
|
||||
throw Error( "Contact::setLayer(): Invalid NULL layer on %s.", getString(this).c_str() );
|
||||
|
||||
if (layer != _layer) {
|
||||
invalidate(false);
|
||||
_layer = layer;
|
||||
}
|
||||
if (layer != _layer) {
|
||||
invalidate( false );
|
||||
_layer = layer;
|
||||
}
|
||||
}
|
||||
|
||||
void Contact::setWidth(DbU::Unit width)
|
||||
|
|
|
@ -777,6 +777,7 @@ string Net::_getString() const
|
|||
{
|
||||
string bs = Inherit::_getString();
|
||||
string ds = "\"" + getString(_name) + "\" ";
|
||||
ds += ((isDeepNet() ) ? "d" : "-");
|
||||
ds += ((_isExternal ) ? "e" : "-");
|
||||
ds += ((_isGlobal ) ? "g" : "-");
|
||||
ds += ((_isAutomatic) ? "a" : "-");
|
||||
|
|
|
@ -227,7 +227,8 @@ namespace Hurricane {
|
|||
|
||||
NetRoutingState* NetRoutingExtension::get ( const Net* net )
|
||||
{
|
||||
if (net == _owner) return _cache;
|
||||
if (not net) return NULL;
|
||||
if ((net == _owner) and _cache) return _cache;
|
||||
_owner = net;
|
||||
|
||||
Property* property = _owner->getProperty( NetRoutingProperty::getPropertyName() );
|
||||
|
|
|
@ -62,8 +62,9 @@ extern "C" {
|
|||
#if defined(__PYTHON_MODULE__)
|
||||
|
||||
// Standard Accessors (Attributes).
|
||||
DirectGetLongAttribute(PyRectilinear_getX, getX, PyRectilinear, Rectilinear)
|
||||
DirectGetLongAttribute(PyRectilinear_getY, getY, PyRectilinear, Rectilinear)
|
||||
DirectGetLongAttribute(PyRectilinear_getX , getX , PyRectilinear, Rectilinear)
|
||||
DirectGetLongAttribute(PyRectilinear_getY , getY , PyRectilinear, Rectilinear)
|
||||
DirectGetBoolAttribute(PyRectilinear_isNonRectangle, isNonRectangle, PyRectilinear, Rectilinear)
|
||||
|
||||
// Standard Destroy (Attribute).
|
||||
DBoDestroyAttribute(PyRectilinear_destroy, PyRectilinear)
|
||||
|
@ -173,6 +174,7 @@ extern "C" {
|
|||
PyMethodDef PyRectilinear_Methods[] =
|
||||
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
|
||||
, "Create a new Rectilinear polygon." }
|
||||
, { "isNonRectangle", (PyCFunction)PyRectilinear_isNonRectangle, METH_NOARGS , "Tells if the shape is not a rectangle." }
|
||||
, { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." }
|
||||
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
|
||||
, { "getBoundingBox", (PyCFunction)PyRectilinear_getBoundingBox, METH_NOARGS , "Return the Rectilinear Bounding Box." }
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace Katana {
|
|||
, _stateCount (1)
|
||||
, _terminals (0)
|
||||
, _ripupCount (0)
|
||||
, _sameRipup (0)
|
||||
, _leftMinExtend (DbU::Max)
|
||||
, _rightMinExtend (DbU::Min)
|
||||
, _attractors ()
|
||||
|
|
|
@ -594,6 +594,7 @@ namespace Katana {
|
|||
if (edge->getReservedCapacity() < hReservedMin)
|
||||
edge->reserveCapacity( hReservedMin - edge->getReservedCapacity() );
|
||||
}
|
||||
gcell->postGlobalAnnotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -863,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();
|
||||
|
||||
|
|
|
@ -470,9 +470,9 @@ namespace Katana {
|
|||
|
||||
queue.repushInvalidateds();
|
||||
|
||||
// if (getProcesseds() == 286892 + 1) {
|
||||
// if (getProcesseds() == 48172 + 1) {
|
||||
// UpdateSession::close();
|
||||
// Breakpoint::stop( 1, "Stopping before revalidating event 286892." );
|
||||
// Breakpoint::stop( 0, "Stopping before revalidating event 3107." );
|
||||
// UpdateSession::open();
|
||||
// }
|
||||
|
||||
|
|
|
@ -594,6 +594,11 @@ namespace Katana {
|
|||
}
|
||||
|
||||
_costs.push_back( new TrackCost(segment1,segment2,track1,track2,track1->getAxis(),symAxis) );
|
||||
cdebug_log(155,0) << "Same Ripup:" << _data1->getSameRipup() << endl;
|
||||
if ((_data1->getSameRipup() > 10) and (track1->getAxis() == segment1->getAxis())) {
|
||||
cdebug_log(155,0) << "Track blacklisted" << endl;
|
||||
_costs.back()->setBlacklisted();
|
||||
}
|
||||
|
||||
cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getRefCandidateAxis())
|
||||
<< " sum:" << DbU::getValueString(_costs.back()->getAxisWeight())
|
||||
|
@ -1399,10 +1404,12 @@ namespace Katana {
|
|||
and ( manipulator.getEvent()->getConstraints().isPonctual()
|
||||
or (isFullBlocked() and (_costs.size() > 7)))
|
||||
and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) {
|
||||
cdebug_log(159,0) << "Next state: MoveUp." << endl;
|
||||
moveUpFlags |= Manipulator::AllowTerminalMoveUp;
|
||||
} else {
|
||||
if ((success = manipulator.slacken(Flags::HalfSlacken))) {
|
||||
nextState = DataNegociate::RipupPerpandiculars;
|
||||
cdebug_log(159,0) << "Next state: RipupPerpandiculars (half-slacken succeeded)." << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
@ -389,14 +395,14 @@ namespace Katana {
|
|||
|
||||
TrackElement* Track::getPrevious ( size_t& index, Net* net ) const
|
||||
{
|
||||
for ( index-- ; index != npos ; index-- ) {
|
||||
cdebug_log(140,0) << index << ":" << _segments[index] << endl;
|
||||
|
||||
if (_segments[index]->getNet() == net) continue;
|
||||
return _segments[index];
|
||||
}
|
||||
cdebug_log(155,0) << "Track::getPrevious() " << index << " for " << net << endl;
|
||||
if ((index == npos) or (index == 0)) return NULL;
|
||||
do {
|
||||
--index;
|
||||
cdebug_log(155,0) << "| " << index << ":" << _segments[index] << endl;
|
||||
if (_segments[index]->getNet() != net) return _segments[index];
|
||||
} while ( index != 0 );
|
||||
index = npos;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -422,8 +428,8 @@ namespace Katana {
|
|||
return;
|
||||
}
|
||||
|
||||
if (position < _min) {
|
||||
cerr << Warning( " Position %s inferior to the lower bound of %s. Returning npos."
|
||||
if (position < _min - getLayerGauge()->getPitch()*2) {
|
||||
cerr << Warning( " Position %s too far outside the lower bound of %s. Returning npos."
|
||||
, DbU::getValueString(position).c_str()
|
||||
, getString(this).c_str() ) << endl;
|
||||
state = BeforeFirstElement;
|
||||
|
@ -431,8 +437,8 @@ namespace Katana {
|
|||
return;
|
||||
}
|
||||
|
||||
if (position > _max) {
|
||||
cerr << Warning( " Position %s superior to the upper bound of %s. Returning npos."
|
||||
if (position > _max + getLayerGauge()->getPitch()*2) {
|
||||
cerr << Warning( " Position %s is too far outside the upper bound of %s. Returning npos."
|
||||
, DbU::getValueString(position).c_str()
|
||||
, getString(this).c_str() ) << endl;
|
||||
state = AfterLastElement;
|
||||
|
@ -682,7 +688,7 @@ namespace Katana {
|
|||
DbU::Unit minFree = _min;
|
||||
cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " (track min)" << endl;
|
||||
|
||||
if (not (state & BeginIsTrackMin) ) {
|
||||
if (not (state & BeginIsTrackMin) and (begin > 0)) {
|
||||
if (_segments[begin]->getNet() == net)
|
||||
getPrevious( begin, net );
|
||||
|
||||
|
@ -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()
|
||||
|
|
|
@ -110,17 +110,18 @@ namespace Katana {
|
|||
|
||||
bool TrackCost::Compare::operator() ( const TrackCost* lhs, const TrackCost* rhs )
|
||||
{
|
||||
if ( lhs->isInfinite () xor rhs->isInfinite () ) return rhs->isInfinite();
|
||||
if ( lhs->isAtRipupLimit() xor rhs->isAtRipupLimit() ) return rhs->isAtRipupLimit();
|
||||
if (lhs->isInfinite () xor rhs->isInfinite ()) return rhs->isInfinite();
|
||||
if (lhs->isAtRipupLimit() xor rhs->isAtRipupLimit()) return rhs->isAtRipupLimit();
|
||||
if (lhs->isBlacklisted() xor rhs->isBlacklisted ()) return rhs->isBlacklisted();
|
||||
|
||||
if ( (_flags & TrackCost::DiscardGlobals)
|
||||
and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) )
|
||||
return rhs->isOverlapGlobal();
|
||||
|
||||
if ( lhs->isHardOverlap() xor rhs->isHardOverlap() ) return rhs->isHardOverlap();
|
||||
if (lhs->isHardOverlap() xor rhs->isHardOverlap()) return rhs->isHardOverlap();
|
||||
|
||||
if ( lhs->_ripupCount + (int)Session::getRipupCost() < rhs->_ripupCount ) return true;
|
||||
if ( lhs->_ripupCount > (int)Session::getRipupCost() + rhs->_ripupCount ) return false;
|
||||
if (lhs->_ripupCount + (int)Session::getRipupCost() < rhs->_ripupCount) return true;
|
||||
if (lhs->_ripupCount > (int)Session::getRipupCost() + rhs->_ripupCount) return false;
|
||||
|
||||
//int lhsRipupCost = (lhs->_dataState<<2) + lhs->_ripupCount;
|
||||
//int rhsRipupCost = (rhs->_dataState<<2) + rhs->_ripupCount;
|
||||
|
@ -132,7 +133,7 @@ namespace Katana {
|
|||
// if ( lhs->_longuestOverlap > rhs->_longuestOverlap ) return false;
|
||||
//}
|
||||
|
||||
if ( lhs->isOverlap() xor rhs->isOverlap() ) return rhs->isOverlap();
|
||||
if (lhs->isOverlap() xor rhs->isOverlap()) return rhs->isOverlap();
|
||||
|
||||
if (not (_flags & TrackCost::IgnoreTerminals)) {
|
||||
if ( lhs->_terminals < rhs->_terminals ) return true;
|
||||
|
@ -166,15 +167,15 @@ namespace Katana {
|
|||
#endif
|
||||
|
||||
if ( not (_flags & TrackCost::IgnoreAxisWeight) ) {
|
||||
if ( lhs->_axisWeight < rhs->_axisWeight ) return true;
|
||||
if ( lhs->_axisWeight > rhs->_axisWeight ) return false;
|
||||
if (lhs->_axisWeight < rhs->_axisWeight) return true;
|
||||
if (lhs->_axisWeight > rhs->_axisWeight) return false;
|
||||
}
|
||||
|
||||
if ( lhs->_deltaPerpand < rhs->_deltaPerpand ) return true;
|
||||
if ( lhs->_deltaPerpand > rhs->_deltaPerpand ) return false;
|
||||
if (lhs->_deltaPerpand < rhs->_deltaPerpand) return true;
|
||||
if (lhs->_deltaPerpand > rhs->_deltaPerpand) return false;
|
||||
|
||||
if ( lhs->_distanceToFixed > rhs->_distanceToFixed ) return true;
|
||||
if ( lhs->_distanceToFixed < rhs->_distanceToFixed ) return false;
|
||||
if (lhs->_distanceToFixed > rhs->_distanceToFixed) return true;
|
||||
if (lhs->_distanceToFixed < rhs->_distanceToFixed) return false;
|
||||
|
||||
return lhs->getTrack(0)->getAxis() < rhs->getTrack(0)->getAxis();
|
||||
}
|
||||
|
|
|
@ -478,6 +478,8 @@ namespace Katana {
|
|||
|
||||
void TrackSegment::revalidate ()
|
||||
{
|
||||
DebugSession::open( getNet(), 159, 160 );
|
||||
|
||||
unsetFlags( TElemCreated );
|
||||
cdebug_log(159,0) << "revalidate() - " << this << endl;
|
||||
|
||||
|
@ -501,11 +503,17 @@ namespace Katana {
|
|||
}
|
||||
}
|
||||
unsetFlags( TElemInvalidated );
|
||||
|
||||
DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
void TrackSegment::setAxis ( DbU::Unit axis, uint32_t flags )
|
||||
{
|
||||
if (_data) {
|
||||
if (axis == getAxis()) _data->incSameRipup();
|
||||
else _data->resetSameRipup();
|
||||
}
|
||||
_base->setAxis( axis, flags );
|
||||
invalidate();
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ namespace Katana {
|
|||
inline uint32_t getState () const;
|
||||
inline uint32_t getStateCount () const;
|
||||
inline uint32_t getRipupCount () const;
|
||||
inline uint32_t getSameRipup () const;
|
||||
inline uint32_t getStateAndRipupCount () const;
|
||||
DbU::Unit getWiringDelta ( DbU::Unit axis ) const;
|
||||
inline const vector<TrackElement*>& getPerpandiculars () const;
|
||||
|
@ -87,6 +88,8 @@ namespace Katana {
|
|||
inline void decRipupCount ();
|
||||
inline void resetRipupCount ();
|
||||
inline void resetStateCount ();
|
||||
inline void resetSameRipup ();
|
||||
inline void incSameRipup ();
|
||||
void update ();
|
||||
static string getStateString ( uint32_t state, unsigned int stateCount );
|
||||
static string getStateString ( DataNegociate* );
|
||||
|
@ -103,6 +106,7 @@ namespace Katana {
|
|||
unsigned int _stateCount : 5;
|
||||
unsigned int _terminals : 5;
|
||||
unsigned int _ripupCount : 16;
|
||||
unsigned int _sameRipup : 8;
|
||||
DbU::Unit _leftMinExtend;
|
||||
DbU::Unit _rightMinExtend;
|
||||
vector<DbU::Unit> _attractors;
|
||||
|
@ -124,6 +128,7 @@ namespace Katana {
|
|||
inline uint32_t DataNegociate::getState () const { return _state; }
|
||||
inline uint32_t DataNegociate::getTerminals () const { return _terminals; }
|
||||
inline uint32_t DataNegociate::getRipupCount () const { return _ripupCount; }
|
||||
inline uint32_t DataNegociate::getSameRipup () const { return _sameRipup; }
|
||||
inline DbU::Unit DataNegociate::getLeftMinExtend () const { return _leftMinExtend; }
|
||||
inline DbU::Unit DataNegociate::getRightMinExtend () const { return _rightMinExtend; }
|
||||
inline Net* DataNegociate::getNet () const { return _net; }
|
||||
|
@ -137,6 +142,8 @@ namespace Katana {
|
|||
inline void DataNegociate::incRipupCount () { _ripupCount++; }
|
||||
inline void DataNegociate::decRipupCount () { if (_ripupCount) _ripupCount--; }
|
||||
inline void DataNegociate::resetRipupCount () { _ripupCount = 0; }
|
||||
inline void DataNegociate::incSameRipup () { _sameRipup++; }
|
||||
inline void DataNegociate::resetSameRipup () { _sameRipup = 0; }
|
||||
inline string DataNegociate::_getTypeName () const { return "DataNegociate"; }
|
||||
|
||||
inline void DataNegociate::setState ( uint32_t state, Flags flags )
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace Katana {
|
|||
, AtRipupLimit = (1 << 18)
|
||||
, IgnoreTerminals = (1 << 19)
|
||||
, IgnoreShort = (1 << 20)
|
||||
, Blacklisted = (1 << 21)
|
||||
, MergeMask = ForGlobal |Blockage|Fixed |Infinite
|
||||
|HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal
|
||||
|GlobalEnclosed |AtRipupLimit
|
||||
|
@ -102,6 +103,7 @@ namespace Katana {
|
|||
inline bool isOverlapGlobal () const;
|
||||
inline bool isGlobalEnclosed () const;
|
||||
inline bool isAtRipupLimit () const;
|
||||
inline bool isBlacklisted () const;
|
||||
bool isFree () const;
|
||||
inline bool isSymmetric () const;
|
||||
inline bool isWide () const;
|
||||
|
@ -148,6 +150,7 @@ namespace Katana {
|
|||
inline void setOverlapGlobal ();
|
||||
inline void setGlobalEnclosed ();
|
||||
inline void setAtRipupLimit ();
|
||||
inline void setBlacklisted ();
|
||||
inline void incTerminals ( uint32_t );
|
||||
inline void incDelta ( DbU::Unit );
|
||||
inline void incDeltaPerpand ( DbU::Unit );
|
||||
|
@ -208,6 +211,7 @@ namespace Katana {
|
|||
inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; }
|
||||
inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; }
|
||||
inline bool TrackCost::isAtRipupLimit () const { return _flags & AtRipupLimit; }
|
||||
inline bool TrackCost::isBlacklisted () const { return _flags & Blacklisted; }
|
||||
inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; }
|
||||
inline bool TrackCost::isWide () const { return (_span > 1); }
|
||||
inline bool TrackCost::doIgnoreShort () const { return _flags & IgnoreShort; }
|
||||
|
@ -245,6 +249,7 @@ namespace Katana {
|
|||
inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; }
|
||||
inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; }
|
||||
inline void TrackCost::setAtRipupLimit () { _flags |= AtRipupLimit; }
|
||||
inline void TrackCost::setBlacklisted () { _flags |= Blacklisted; }
|
||||
inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; }
|
||||
inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; }
|
||||
inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; }
|
||||
|
|
Loading…
Reference in New Issue