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
|
void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
|
||||||
{
|
{
|
||||||
|
cdebug_log(145,1) << "AutoContact::getDepthSpan() of " << this << endl;
|
||||||
minDepth = (size_t)-1;
|
minDepth = (size_t)-1;
|
||||||
maxDepth = 0;
|
maxDepth = 0;
|
||||||
|
|
||||||
Component* anchor = getAnchor ();
|
Component* anchor = getAnchor ();
|
||||||
if (anchor) {
|
if (anchor) {
|
||||||
|
cdebug_log(145,0) << "* Anchor depth: "
|
||||||
|
<< Session::getRoutingGauge()->getLayerDepth(anchor->getLayer())<< endl;
|
||||||
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
||||||
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
|
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()) );
|
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
|
||||||
maxDepth = std::max( maxDepth, 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) {
|
if (delta > 1) {
|
||||||
//_segment = _segment->makeDogleg( this );
|
//_segment = _segment->makeDogleg( this );
|
||||||
_segment->makeDogleg( this );
|
_segment->makeDogleg( this );
|
||||||
cdebug_log(145,0) << "Update seg: " << _segment << endl;
|
|
||||||
delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) );
|
delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) );
|
||||||
|
cdebug_log(145,0) << "Delta: " << delta << " Update seg: " << _segment << endl;
|
||||||
}
|
}
|
||||||
else if (delta == 0) setLayerAndWidth( delta, anchorDepth );
|
if (delta == 0) setLayerAndWidth( delta, anchorDepth );
|
||||||
else if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
|
if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
|
||||||
}
|
}
|
||||||
_segment->invalidate( this );
|
_segment->invalidate( this );
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,9 @@ namespace Anabatic {
|
||||||
setFlags( CntBadTopology );
|
setFlags( CntBadTopology );
|
||||||
} else {
|
} else {
|
||||||
if (delta > 1) {
|
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 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
|
||||||
_horizontal1->makeDogleg(this);
|
_horizontal1->makeDogleg(this);
|
||||||
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;
|
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;
|
||||||
|
|
|
@ -14,18 +14,19 @@
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "hurricane/Bug.h"
|
#include "hurricane/Bug.h"
|
||||||
#include "hurricane/Error.h"
|
#include "hurricane/Error.h"
|
||||||
#include "hurricane/DebugSession.h"
|
#include "hurricane/Warning.h"
|
||||||
#include "hurricane/ViaLayer.h"
|
#include "hurricane/DebugSession.h"
|
||||||
#include "hurricane/RoutingPad.h"
|
#include "hurricane/ViaLayer.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "hurricane/RoutingPad.h"
|
||||||
#include "anabatic/Configuration.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
#include "anabatic/AutoContactTerminal.h"
|
#include "anabatic/Configuration.h"
|
||||||
#include "anabatic/AutoContactTurn.h"
|
#include "anabatic/AutoContactTerminal.h"
|
||||||
#include "anabatic/AutoHorizontal.h"
|
#include "anabatic/AutoContactTurn.h"
|
||||||
#include "anabatic/AutoVertical.h"
|
#include "anabatic/AutoHorizontal.h"
|
||||||
|
#include "anabatic/AutoVertical.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Anabatic {
|
namespace Anabatic {
|
||||||
|
@ -33,8 +34,10 @@ namespace Anabatic {
|
||||||
|
|
||||||
using std::min;
|
using std::min;
|
||||||
using std::max;
|
using std::max;
|
||||||
using Hurricane::Error;
|
using std::abs;
|
||||||
using Hurricane::Bug;
|
using Hurricane::Bug;
|
||||||
|
using Hurricane::Error;
|
||||||
|
using Hurricane::Warning;
|
||||||
using Hurricane::DebugSession;
|
using Hurricane::DebugSession;
|
||||||
using Hurricane::ViaLayer;
|
using Hurricane::ViaLayer;
|
||||||
using Hurricane::RoutingPad;
|
using Hurricane::RoutingPad;
|
||||||
|
@ -52,8 +55,6 @@ namespace Anabatic {
|
||||||
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
|
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
|
||||||
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
|
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
|
||||||
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }
|
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }
|
||||||
void AutoHorizontal::setDuSource ( DbU::Unit du ) { _horizontal->setDxSource(du); }
|
|
||||||
void AutoHorizontal::setDuTarget ( DbU::Unit du ) { _horizontal->setDxTarget(du); }
|
|
||||||
string AutoHorizontal::_getTypeName () const { return "AutoHorizontal"; }
|
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
|
Interval AutoHorizontal::getSourceConstraints ( Flags flags ) const
|
||||||
{
|
{
|
||||||
if (flags & Flags::NativeConstraints) {
|
if (flags & Flags::NativeConstraints) {
|
||||||
|
@ -487,17 +512,9 @@ namespace Anabatic {
|
||||||
void AutoHorizontal::updateOrient ()
|
void AutoHorizontal::updateOrient ()
|
||||||
{
|
{
|
||||||
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) {
|
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) {
|
||||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
cdebug_log(149,1) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||||
if (isAtMinArea()) {
|
_horizontal->invert();
|
||||||
DbU::Unit sourceX = _horizontal->getSourceX();
|
cdebug_log(149,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
|
||||||
DbU::Unit targetX = _horizontal->getTargetX();
|
|
||||||
_horizontal->invert();
|
|
||||||
setDuSource( sourceX - getSourceU() );
|
|
||||||
setDuTarget( targetX - getTargetU() );
|
|
||||||
} else {
|
|
||||||
_horizontal->invert();
|
|
||||||
}
|
|
||||||
cdebug_log(145,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
|
|
||||||
|
|
||||||
uint64_t spinFlags = _flags & SegDepthSpin;
|
uint64_t spinFlags = _flags & SegDepthSpin;
|
||||||
unsetFlags( SegDepthSpin );
|
unsetFlags( SegDepthSpin );
|
||||||
|
@ -515,6 +532,7 @@ namespace Anabatic {
|
||||||
unsetFlags( SegStrongTerminal );
|
unsetFlags( SegStrongTerminal );
|
||||||
if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal );
|
if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal );
|
||||||
if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal );
|
if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal );
|
||||||
|
cdebug_tabw(149,-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -679,8 +679,12 @@ namespace Anabatic {
|
||||||
|
|
||||||
void AutoSegment::revalidate ()
|
void AutoSegment::revalidate ()
|
||||||
{
|
{
|
||||||
|
DebugSession::open( getNet(), 159, 160 );
|
||||||
cdebug_log(149,0) << "AutoSegment::revalidate() " << this << endl;
|
cdebug_log(149,0) << "AutoSegment::revalidate() " << this << endl;
|
||||||
if (not isInvalidated()) return;
|
if (not isInvalidated()) {
|
||||||
|
DebugSession::close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cdebug_tabw(149,1);
|
cdebug_tabw(149,1);
|
||||||
|
|
||||||
|
@ -715,9 +719,9 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
Interval oldSpan = Interval( _sourcePosition, _targetPosition );
|
Interval oldSpan = Interval( _sourcePosition, _targetPosition );
|
||||||
if (not expandToMinLength(oldSpan)) {
|
if (_flags & SegCreated) oldSpan.makeEmpty();
|
||||||
unexpandToMinLength();
|
expandToMinLength( oldSpan );
|
||||||
}
|
if (_flags & SegAtMinArea) unexpandToMinLength();
|
||||||
updatePositions();
|
updatePositions();
|
||||||
|
|
||||||
unsigned int observerFlags = Revalidate;
|
unsigned int observerFlags = Revalidate;
|
||||||
|
@ -735,6 +739,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
cdebug_log(149,0) << "Updated: " << this << endl;
|
cdebug_log(149,0) << "Updated: " << this << endl;
|
||||||
cdebug_tabw(149,-1);
|
cdebug_tabw(149,-1);
|
||||||
|
DebugSession::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -770,16 +775,16 @@ namespace Anabatic {
|
||||||
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
||||||
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
||||||
else cap = getViaToSameCap (depth);
|
else cap = getViaToSameCap (depth);
|
||||||
cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
|
// cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
|
||||||
<< " VIA cap:" << DbU::getValueString(cap)
|
// << " VIA cap:" << DbU::getValueString(cap)
|
||||||
<< " t:" << (getFlags() & SegSourceBottom)
|
// << " t:" << (getFlags() & SegSourceBottom)
|
||||||
<< " b:" << (getFlags() & SegSourceTop)
|
// << " b:" << (getFlags() & SegSourceTop)
|
||||||
<< endl;
|
// << endl;
|
||||||
if (not (flags & Flags::NoSegExt)) {
|
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) {
|
if (-getDuSource() > cap) {
|
||||||
cap = -getDuSource();
|
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);
|
if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
|
||||||
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
|
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
|
||||||
else cap = getViaToSameCap (depth);
|
else cap = getViaToSameCap (depth);
|
||||||
cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
|
// cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
|
||||||
<< " VIA cap:" << DbU::getValueString(cap)
|
// << " VIA cap:" << DbU::getValueString(cap)
|
||||||
<< " t:" << (getFlags() & SegSourceBottom)
|
// << " t:" << (getFlags() & SegSourceBottom)
|
||||||
<< " b:" << (getFlags() & SegSourceTop)
|
// << " b:" << (getFlags() & SegSourceTop)
|
||||||
<< endl;
|
// << endl;
|
||||||
if (not (flags & Flags::NoSegExt)) {
|
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) {
|
if (getDuTarget() > cap) {
|
||||||
cap = getDuTarget();
|
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 not (flags & Flags::NoMinLength)
|
||||||
// and (flags & Flags::Target)
|
// and (flags & Flags::Target)
|
||||||
// and (getMinimalLength(depth) != 0.0)
|
// and (getMinimalLength(depth) != 0.0)
|
||||||
// and isMiddleStack() ) {
|
// and isNearMinArea() ) {
|
||||||
// DbU::Unit realLength = getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
|
// DbU::Unit realLength = getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
|
||||||
// + getAnchoredLength();
|
// + getAnchoredLength();
|
||||||
// if (realLength + cap < getMinimalLength(depth)) {
|
// if (realLength + cap < getMinimalLength(depth)) {
|
||||||
|
@ -901,12 +906,12 @@ namespace Anabatic {
|
||||||
sourceAxis = getSourceU();
|
sourceAxis = getSourceU();
|
||||||
targetAxis = getTargetU();
|
targetAxis = getTargetU();
|
||||||
|
|
||||||
if (not isNotAligned()) {
|
//if (not isNotAligned()) {
|
||||||
for( AutoSegment* aligned : const_cast<AutoSegment*>(this)->getAligneds() ) {
|
for( AutoSegment* aligned : const_cast<AutoSegment*>(this)->getAligneds() ) {
|
||||||
sourceAxis = std::min( sourceAxis, aligned->getSourceU() );
|
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 )
|
AutoSegment* AutoSegment::canonize ( Flags flags )
|
||||||
{
|
{
|
||||||
cdebug_log(149,0) << "canonize() - " << this << endl;
|
cdebug_log(149,0) << "canonize() - " << this << endl;
|
||||||
|
if (Session::getAnabatic()->isCanonizeDisabled()) return this;
|
||||||
|
|
||||||
// if (isCanonical() and isGlobal()) {
|
// if (isCanonical() and isGlobal()) {
|
||||||
// cdebug_log(149,0) << "* " << this << " canonical" << endl;
|
// 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;
|
cdebug_log(149,0) << "AutoSegment::isNearMinArea() - " << this << endl;
|
||||||
if (not isCanonical()) return false;
|
|
||||||
if (isNonPref()) return false;
|
if (isNonPref()) return false;
|
||||||
if (isGlobal()) {
|
if (isGlobal()) {
|
||||||
if (getLength() > getPPitch()) return false;
|
if (getLength() > getPPitch()) return false;
|
||||||
cdebug_log(149,0) << "| Considering this global anyway because it is too short. " << endl;
|
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 sourceAxis = 0;
|
||||||
DbU::Unit targetAxis = 0;
|
DbU::Unit targetAxis = 0;
|
||||||
getEndAxes( sourceAxis, targetAxis );
|
getEndAxes( sourceAxis, targetAxis );
|
||||||
|
@ -1665,43 +1634,38 @@ namespace Anabatic {
|
||||||
cdebug_log(149,0) << "| Canonical axis length superior to P-Pitch " << this << endl;
|
cdebug_log(149,0) << "| Canonical axis length superior to P-Pitch " << this << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cdebug_log(149,0) << " Middle stack or terminal bound." << endl;
|
cdebug_log(149,0) << " Length below P-Pitch." << endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool AutoSegment::isUnderMinLength () const
|
void AutoSegment::expandToMinLength ( Interval span )
|
||||||
{
|
{
|
||||||
return false;
|
if (not isNearMinArea()) return;
|
||||||
// cdebug_log(149,0) << "AutoSegment::isUnderMinLength() - " << this << endl;
|
DebugSession::open( getNet(), 149, 160 );
|
||||||
// if (not isMiddleStack()) return false;
|
|
||||||
// DbU::Unit spanLength = getSpanLength();
|
|
||||||
// DbU::Unit minimalLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
|
|
||||||
// cdebug_log(149,0) << " span=" << DbU::getValueString(spanLength)
|
|
||||||
// << " < min=" << DbU::getValueString(minimalLength)<< endl;
|
|
||||||
// return spanLength < minimalLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool AutoSegment::expandToMinLength ( Interval span )
|
|
||||||
{
|
|
||||||
if (not isMiddleStack()) return false;
|
|
||||||
cdebug_log(149,1) << "AutoSegment::expandToMinLength() " << this << endl;
|
cdebug_log(149,1) << "AutoSegment::expandToMinLength() " << this << endl;
|
||||||
cdebug_log(149,0) << "In span=" << span << endl;
|
cdebug_log(149,0) << "In span=" << span << endl;
|
||||||
cdebug_log(149,0) << "Before: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly ))
|
cdebug_log(149,0) << "Before: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly ))
|
||||||
<< " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly ))
|
<< " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly ))
|
||||||
<< "]" << endl;
|
<< "]" << endl;
|
||||||
|
|
||||||
DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly );
|
DbU::Unit halfMinSpacing = getLayer()->getMinimalSpacing() / 2;
|
||||||
DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly );
|
DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::LayerCapOnly );
|
||||||
DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap;
|
DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::LayerCapOnly );
|
||||||
DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
|
DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap;
|
||||||
if (techMinLength <= segMinLength) {
|
DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
|
||||||
cdebug_log(149,0) << "Above minimal length (" << DbU::getValueString(segMinLength)
|
cdebug_log(149,0) << "Minimal length " << DbU::getValueString(techMinLength)
|
||||||
<< " >= " << DbU::getValueString(techMinLength) << ")" << endl;
|
<< " vs. current length " << DbU::getValueString(segMinLength) << endl;
|
||||||
|
if (segMinLength >= techMinLength) {
|
||||||
|
if (segMinLength == techMinLength)
|
||||||
|
setFlags( SegAtMinArea );
|
||||||
cdebug_tabw(149,-1);
|
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 oneGrid = DbU::fromGrid( 1 );
|
||||||
DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap;
|
DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap;
|
||||||
|
@ -1711,11 +1675,20 @@ namespace Anabatic {
|
||||||
if (sourceExpand % oneGrid)
|
if (sourceExpand % oneGrid)
|
||||||
sourceExpand -= oneGrid + sourceExpand % oneGrid;
|
sourceExpand -= oneGrid + sourceExpand % oneGrid;
|
||||||
if (not span.isEmpty()) {
|
if (not span.isEmpty()) {
|
||||||
DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand);
|
DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand + halfMinSpacing);
|
||||||
if (shiftLeft < 0) {
|
if (shiftLeft < 0) {
|
||||||
|
if (targetExpand + shiftLeft < targetCap)
|
||||||
|
shiftLeft = targetCap - targetExpand;
|
||||||
targetExpand += shiftLeft;
|
targetExpand += shiftLeft;
|
||||||
sourceExpand += 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 );
|
setDuSource( sourceExpand );
|
||||||
setDuTarget( targetExpand );
|
setDuTarget( targetExpand );
|
||||||
|
@ -1726,18 +1699,75 @@ namespace Anabatic {
|
||||||
<< "] expand:" << DbU::getValueString(techMinLength - segMinLength)<< endl;
|
<< "] expand:" << DbU::getValueString(techMinLength - segMinLength)<< endl;
|
||||||
setFlags( SegAtMinArea );
|
setFlags( SegAtMinArea );
|
||||||
cdebug_tabw(149,-1);
|
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;
|
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 );
|
setDuSource( 0 );
|
||||||
setDuTarget( 0 );
|
cdebug_log(149,0) << "Shrink target of " << DbU::getValueString(shrink) << endl;
|
||||||
unsetFlags( SegAtMinArea );
|
margin = duTarget - targetCap;
|
||||||
return true;
|
if (margin > shrink)
|
||||||
|
setDuTarget( duTarget - shrink );
|
||||||
|
else {
|
||||||
|
cdebug_log(149,0) << "Target reset" << endl;
|
||||||
|
setDuTarget( 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2302,6 +2332,8 @@ namespace Anabatic {
|
||||||
setWidth( hside );
|
setWidth( hside );
|
||||||
source->setSizes( hside, vside );
|
source->setSizes( hside, vside );
|
||||||
target->setSizes( hside, vside );
|
target->setSizes( hside, vside );
|
||||||
|
setDuSource( 0 );
|
||||||
|
setDuTarget( 0 );
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
@ -2710,6 +2742,7 @@ namespace Anabatic {
|
||||||
state += isFixed () ?" F":" -";
|
state += isFixed () ?" F":" -";
|
||||||
state += isFixedAxis () ? "X": "-";
|
state += isFixedAxis () ? "X": "-";
|
||||||
state += isUnsetAxis () ? "u": "-";
|
state += isUnsetAxis () ? "u": "-";
|
||||||
|
state += isAtMinArea () ? "a": "-";
|
||||||
state += isStrap () ? "S": "-";
|
state += isStrap () ? "S": "-";
|
||||||
state += isUnbreakable () ? "U": "-";
|
state += isUnbreakable () ? "U": "-";
|
||||||
state += isCanonical () ? "C": "-";
|
state += isCanonical () ? "C": "-";
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "hurricane/Bug.h"
|
#include "hurricane/Bug.h"
|
||||||
|
#include "hurricane/Warning.h"
|
||||||
#include "hurricane/ViaLayer.h"
|
#include "hurricane/ViaLayer.h"
|
||||||
#include "hurricane/Vertical.h"
|
#include "hurricane/Vertical.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
|
@ -29,8 +30,10 @@ namespace Anabatic {
|
||||||
|
|
||||||
using std::min;
|
using std::min;
|
||||||
using std::max;
|
using std::max;
|
||||||
using Hurricane::Error;
|
using std::abs;
|
||||||
using Hurricane::Bug;
|
using Hurricane::Bug;
|
||||||
|
using Hurricane::Error;
|
||||||
|
using Hurricane::Warning;
|
||||||
using Hurricane::ViaLayer;
|
using Hurricane::ViaLayer;
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,8 +49,6 @@ namespace Anabatic {
|
||||||
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
|
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
|
||||||
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
|
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
|
||||||
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }
|
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }
|
||||||
void AutoVertical::setDuSource ( DbU::Unit du ) { _vertical->setDySource(du); }
|
|
||||||
void AutoVertical::setDuTarget ( DbU::Unit du ) { _vertical->setDyTarget(du); }
|
|
||||||
string AutoVertical::_getTypeName () const { return "AutoVertical"; }
|
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
|
Interval AutoVertical::getSourceConstraints ( Flags flags ) const
|
||||||
{
|
{
|
||||||
if (flags & Flags::NativeConstraints) {
|
if (flags & Flags::NativeConstraints) {
|
||||||
|
@ -382,10 +407,6 @@ namespace Anabatic {
|
||||||
if (_vertical->getTargetY() < _vertical->getSourceY()) {
|
if (_vertical->getTargetY() < _vertical->getSourceY()) {
|
||||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||||
_vertical->invert();
|
_vertical->invert();
|
||||||
DbU::Unit duSource = getDuSource();
|
|
||||||
DbU::Unit duTarget = getDuTarget();
|
|
||||||
setDuSource( -duTarget );
|
|
||||||
setDuTarget( -duSource );
|
|
||||||
|
|
||||||
unsigned int spinFlags = _flags & SegDepthSpin;
|
unsigned int spinFlags = _flags & SegDepthSpin;
|
||||||
unsetFlags( SegDepthSpin );
|
unsetFlags( SegDepthSpin );
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace Anabatic {
|
||||||
const BaseFlags Flags::DestroyGCell = (1L << 7);
|
const BaseFlags Flags::DestroyGCell = (1L << 7);
|
||||||
const BaseFlags Flags::DestroyBaseContact = (1L << 8);
|
const BaseFlags Flags::DestroyBaseContact = (1L << 8);
|
||||||
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
|
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
|
||||||
|
const BaseFlags Flags::DisableCanonize = (1L << 10);
|
||||||
// Flags for NetDatas objects states only.
|
// Flags for NetDatas objects states only.
|
||||||
const BaseFlags Flags::GlobalFixed = (1L << 5);
|
const BaseFlags Flags::GlobalFixed = (1L << 5);
|
||||||
const BaseFlags Flags::GlobalEstimated = (1L << 6);
|
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 )
|
void GCell::addBlockage ( size_t depth, DbU::Unit length )
|
||||||
{
|
{
|
||||||
if (depth >= _depth) return;
|
if (depth >= _depth) return;
|
||||||
|
@ -1371,6 +1391,7 @@ namespace Anabatic {
|
||||||
if (found) {
|
if (found) {
|
||||||
cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
|
cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
|
||||||
_contacts.pop_back();
|
_contacts.pop_back();
|
||||||
|
_flags |= Flags::Invalidated;
|
||||||
} else {
|
} else {
|
||||||
cerr << Bug("%p:%s do not belong to %s."
|
cerr << Bug("%p:%s do not belong to %s."
|
||||||
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
|
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
|
||||||
|
@ -1404,6 +1425,7 @@ namespace Anabatic {
|
||||||
, _getString().c_str(), getString(segment).c_str() ) << endl;
|
, _getString().c_str(), getString(segment).c_str() ) << endl;
|
||||||
|
|
||||||
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
|
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
|
||||||
|
_flags |= Flags::Invalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1429,6 +1451,7 @@ namespace Anabatic {
|
||||||
, getString(segment).c_str() ) << endl;
|
, getString(segment).c_str() ) << endl;
|
||||||
|
|
||||||
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
|
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
|
||||||
|
_flags |= Flags::Invalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1528,13 +1551,20 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the blockages.
|
// Add the blockages.
|
||||||
|
int contiguousNonSaturated = 0;
|
||||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||||
uLengths2[i] += _blockages[i];
|
uLengths2[i] += _blockages[i];
|
||||||
if (not i) continue;
|
if (not i) continue;
|
||||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.40*(float)(width*height)) {
|
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
|
||||||
flags() |= Flags::GoStraight;
|
continue;
|
||||||
//cerr << "| Set GoStraight on " << this << endl;
|
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.
|
// Compute the number of non pass-through tracks.
|
||||||
|
@ -1880,6 +1910,13 @@ namespace Anabatic {
|
||||||
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||||
record->add( getSlot ( s.str(), &_densities[depth] ) );
|
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;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "hurricane/Instance.h"
|
#include "hurricane/Instance.h"
|
||||||
#include "hurricane/Vertical.h"
|
#include "hurricane/Vertical.h"
|
||||||
#include "hurricane/Horizontal.h"
|
#include "hurricane/Horizontal.h"
|
||||||
|
#include "hurricane/Rectilinear.h"
|
||||||
#include "crlcore/AllianceFramework.h"
|
#include "crlcore/AllianceFramework.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
#include "anabatic/AutoContactTerminal.h"
|
#include "anabatic/AutoContactTerminal.h"
|
||||||
|
@ -220,6 +221,7 @@ namespace Anabatic {
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
using Hurricane::Warning;
|
using Hurricane::Warning;
|
||||||
using Hurricane::Bug;
|
using Hurricane::Bug;
|
||||||
|
using Hurricane::Rectilinear;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -367,6 +369,8 @@ namespace Anabatic {
|
||||||
, _toFixSegments ()
|
, _toFixSegments ()
|
||||||
, _degree (0)
|
, _degree (0)
|
||||||
, _isTwoMetals (false)
|
, _isTwoMetals (false)
|
||||||
|
, _sourceFlags (0)
|
||||||
|
, _flags (0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
@ -377,6 +381,8 @@ namespace Anabatic {
|
||||||
void NetBuilder::clear ()
|
void NetBuilder::clear ()
|
||||||
{
|
{
|
||||||
_connexity.connexity = 0;
|
_connexity.connexity = 0;
|
||||||
|
_sourceFlags = 0;
|
||||||
|
_flags = 0;
|
||||||
_topology = 0;
|
_topology = 0;
|
||||||
_net = NULL;
|
_net = NULL;
|
||||||
_netData = 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();
|
clear();
|
||||||
|
|
||||||
_isTwoMetals = anbt->getConfiguration()->isTwoMetals();
|
_isTwoMetals = anbt->getConfiguration()->isTwoMetals();
|
||||||
|
_sourceFlags = sourceFlags;
|
||||||
_sourceContact = sourceContact;
|
_sourceContact = sourceContact;
|
||||||
_fromHook = fromHook;
|
_fromHook = fromHook;
|
||||||
|
|
||||||
|
@ -470,6 +480,12 @@ namespace Anabatic {
|
||||||
throw Error( mismatchGCell );
|
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()) {
|
if (not _gcell->isMatrix()) {
|
||||||
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
|
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
|
||||||
cdebug_log(145,0) << "| " << gcell << endl;
|
cdebug_log(145,0) << "| " << gcell << endl;
|
||||||
|
@ -489,11 +505,25 @@ namespace Anabatic {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer->getMask() == Session::getRoutingLayer(0)->getMask()) _connexity.fields.M1++; // M1 V
|
bool isPin = (dynamic_cast<Pin*>( rp->getOccurrence().getEntity() ) != nullptr);
|
||||||
else if (layer->getMask() == Session::getRoutingLayer(1)->getMask()) _connexity.fields.M2++; // M2 H
|
size_t rpDepth = 0;
|
||||||
else if (layer->getMask() == Session::getRoutingLayer(2)->getMask()) _connexity.fields.M3++; // M3 V
|
for ( size_t depth=0 ; depth < Session::getRoutingGauge()->getDepth() ; ++depth ) {
|
||||||
else if (layer->getMask() == Session::getRoutingLayer(3)->getMask()) _connexity.fields.M2++; // M4 H
|
if (layer->getMask() == Session::getRoutingLayer(depth)->getMask()) {
|
||||||
else if (layer->getMask() == Session::getRoutingLayer(4)->getMask()) _connexity.fields.M3++; // M5 V
|
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 {
|
else {
|
||||||
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
|
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
|
||||||
, getString(layer->getName()).c_str()
|
, getString(layer->getName()).c_str()
|
||||||
|
@ -502,7 +532,7 @@ namespace Anabatic {
|
||||||
//continue;
|
//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;
|
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) << "NetBuilder::push()" << endl;
|
||||||
cdebug_log(145,0) << "* toHook: " << toHook << endl;
|
cdebug_log(145,0) << "* toHook: " << toHook << endl;
|
||||||
cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl;
|
cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl;
|
||||||
|
cdebug_log(145,0) << "* flags:" << flags << endl;
|
||||||
|
|
||||||
if (not toHook or (toHook == _fromHook)) {
|
if (not toHook or (toHook == _fromHook)) {
|
||||||
if (contact) {
|
if (contact) {
|
||||||
|
@ -571,12 +602,60 @@ namespace Anabatic {
|
||||||
Hook* toHookOpposite = getSegmentOppositeHook( toHook );
|
Hook* toHookOpposite = getSegmentOppositeHook( toHook );
|
||||||
cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl;
|
cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl;
|
||||||
cdebug_log(145,0) << "Pushing (from) " << contact << endl;
|
cdebug_log(145,0) << "Pushing (from) " << contact << endl;
|
||||||
_forks.push( toHookOpposite, contact );
|
_forks.push( toHookOpposite, contact, getFlags() );
|
||||||
|
|
||||||
return true;
|
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 ()
|
void NetBuilder::construct ()
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
|
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
|
||||||
|
@ -589,6 +668,8 @@ namespace Anabatic {
|
||||||
<< "+" << (int)_connexity.fields.Pad
|
<< "+" << (int)_connexity.fields.Pad
|
||||||
<< "] " << _gcell
|
<< "] " << _gcell
|
||||||
<< endl;
|
<< endl;
|
||||||
|
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
|
||||||
|
<< " getFlags():" << getFlags() << endl;
|
||||||
|
|
||||||
if (not isTwoMetals()) {
|
if (not isTwoMetals()) {
|
||||||
_southWestContact = NULL;
|
_southWestContact = NULL;
|
||||||
|
@ -2374,6 +2455,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
Hook* sourceHook = NULL;
|
Hook* sourceHook = NULL;
|
||||||
AutoContact* sourceContact = NULL;
|
AutoContact* sourceContact = NULL;
|
||||||
|
uint64_t sourceFlags = NoFlags;
|
||||||
RoutingPads routingPads = net->getRoutingPads();
|
RoutingPads routingPads = net->getRoutingPads();
|
||||||
size_t degree = routingPads.getSize();
|
size_t degree = routingPads.getSize();
|
||||||
|
|
||||||
|
@ -2412,7 +2494,7 @@ namespace Anabatic {
|
||||||
++connecteds;
|
++connecteds;
|
||||||
segmentFound = true;
|
segmentFound = true;
|
||||||
|
|
||||||
setStartHook( anabatic, hook, NULL );
|
setStartHook( anabatic, hook, NULL, NoFlags );
|
||||||
if (getStateG() == 1) {
|
if (getStateG() == 1) {
|
||||||
if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) {
|
if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) {
|
||||||
cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl;
|
cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl;
|
||||||
|
@ -2440,9 +2522,9 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
cdebug_tabw(145,-1);
|
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) << endl;
|
||||||
cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl;
|
cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl;
|
||||||
cdebug_log(145,0) << endl;
|
cdebug_log(145,0) << endl;
|
||||||
|
@ -2451,18 +2533,21 @@ namespace Anabatic {
|
||||||
|
|
||||||
sourceHook = _forks.getFrom ();
|
sourceHook = _forks.getFrom ();
|
||||||
sourceContact = _forks.getContact();
|
sourceContact = _forks.getContact();
|
||||||
|
sourceFlags = _forks.getFlags ();
|
||||||
_forks.pop();
|
_forks.pop();
|
||||||
|
|
||||||
while ( sourceHook ) {
|
while ( sourceHook ) {
|
||||||
setStartHook( anabatic, sourceHook, sourceContact );
|
setStartHook( anabatic, sourceHook, sourceContact, sourceFlags );
|
||||||
construct();
|
construct();
|
||||||
|
|
||||||
sourceHook = _forks.getFrom();
|
sourceHook = _forks.getFrom ();
|
||||||
sourceContact = _forks.getContact();
|
sourceContact = _forks.getContact();
|
||||||
|
sourceFlags = _forks.getFlags ();
|
||||||
_forks.pop();
|
_forks.pop();
|
||||||
|
|
||||||
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
|
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
|
||||||
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
|
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
|
||||||
|
cdebug_log(145,0) << "Popping (flags) " << sourceFlags << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Session::revalidate();
|
Session::revalidate();
|
||||||
|
@ -2473,10 +2558,11 @@ namespace Anabatic {
|
||||||
for ( ; iover != overconstraineds.end() ; ++iover ) {
|
for ( ; iover != overconstraineds.end() ; ++iover ) {
|
||||||
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
|
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
|
||||||
}
|
}
|
||||||
|
Session::revalidate();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Session::revalidate();
|
|
||||||
fixSegments();
|
fixSegments();
|
||||||
|
Session::revalidate();
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
|
|
||||||
//DebugSession::close();
|
//DebugSession::close();
|
||||||
|
|
|
@ -104,6 +104,7 @@ namespace Anabatic {
|
||||||
viaSide = Session::getViaWidth( rpDepth );
|
viaSide = Session::getViaWidth( rpDepth );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if THIS_IS_DISABLED
|
||||||
// Non-M1 terminal or punctual M1 protections.
|
// Non-M1 terminal or punctual M1 protections.
|
||||||
if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) {
|
if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) {
|
||||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||||
|
@ -177,17 +178,45 @@ namespace Anabatic {
|
||||||
getRpLookup().insert( make_pair(rp,segment) );
|
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 (sourcePosition != targetPosition) {
|
||||||
if (flags & DoSourceContact)
|
if (flags & DoSourceContact)
|
||||||
source = AutoContactTerminal::create( sourceGCell
|
source = AutoContactTerminal::create( gcell
|
||||||
, rp
|
, rp
|
||||||
, rpLayer
|
, rpLayer
|
||||||
, sourcePosition
|
, sourcePosition
|
||||||
, viaSide, viaSide
|
, viaSide, viaSide
|
||||||
);
|
);
|
||||||
if (flags & DoTargetContact)
|
if (flags & DoTargetContact)
|
||||||
target = AutoContactTerminal::create( targetGCell
|
target = AutoContactTerminal::create( gcell
|
||||||
, rp
|
, rp
|
||||||
, rpLayer
|
, rpLayer
|
||||||
, targetPosition
|
, targetPosition
|
||||||
|
@ -245,7 +274,7 @@ namespace Anabatic {
|
||||||
if (flags & (VSmall|UseNonPref)) {
|
if (flags & (VSmall|UseNonPref)) {
|
||||||
cdebug_log(145,0) << "case: UseNonPref" << endl;
|
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 );
|
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|useNonPref );
|
||||||
rpSourceContact = subContact1;
|
rpSourceContact = subContact1;
|
||||||
}
|
}
|
||||||
|
@ -254,19 +283,19 @@ namespace Anabatic {
|
||||||
cdebug_log(145,0) << "case: HSmall" << endl;
|
cdebug_log(145,0) << "case: HSmall" << endl;
|
||||||
|
|
||||||
AutoContact* subContact1 = rpSourceContact;
|
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 );
|
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
||||||
rpSourceContact = subContact2;
|
rpSourceContact = subContact2;
|
||||||
|
|
||||||
if (flags & Punctual) {
|
if (flags & Punctual) {
|
||||||
cdebug_log(145,0) << "case: HSmall + Punctual" << endl;
|
cdebug_log(145,0) << "case: HSmall + Punctual" << endl;
|
||||||
subContact1 = subContact2;
|
subContact1 = subContact2;
|
||||||
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||||
AutoSegment::create( subContact1, subContact2, Flags::Vertical );
|
AutoSegment::create( subContact1, subContact2, Flags::Vertical, rpDepth+2 );
|
||||||
|
|
||||||
subContact1 = subContact2;
|
subContact1 = subContact2;
|
||||||
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
|
||||||
|
|
||||||
rpSourceContact = subContact2;
|
rpSourceContact = subContact2;
|
||||||
}
|
}
|
||||||
|
@ -277,12 +306,14 @@ namespace Anabatic {
|
||||||
AutoContact* subContact1 = NULL;
|
AutoContact* subContact1 = NULL;
|
||||||
|
|
||||||
if (flags & HAccess) {
|
if (flags & HAccess) {
|
||||||
if (flags & HAccessEW)
|
cdebug_log(145,0) << "HAccess" << endl;
|
||||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
if (flags & HAccessEW) {
|
||||||
else
|
cdebug_log(145,0) << "HAccessEW" << endl;
|
||||||
subContact1 = AutoContactTurn::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(rpDepth+1) );
|
||||||
|
|
||||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical );
|
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical, rpDepth+1 );
|
||||||
} else {
|
} else {
|
||||||
#if OFFGRID_M2_DISABLED
|
#if OFFGRID_M2_DISABLED
|
||||||
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
||||||
|
@ -299,9 +330,14 @@ namespace Anabatic {
|
||||||
rpSourceContact = subContact1;
|
rpSourceContact = subContact1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (Session::getRoutingGauge()->isSuperPitched()) {
|
||||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
cdebug_log(145,0) << "Vertical access & super-pitched" << endl;
|
||||||
AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal );
|
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;
|
rpSourceContact = subContact1;
|
||||||
}
|
}
|
||||||
|
@ -456,7 +492,15 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
|
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) {
|
if (getConnexity().fields.globals == 2) {
|
||||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||||
|
@ -466,20 +510,20 @@ namespace Anabatic {
|
||||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||||
if (south()) swapCornerContacts();
|
if (south()) swapCornerContacts();
|
||||||
|
|
||||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
|
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical, vDepth );
|
||||||
} else {
|
} else {
|
||||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||||
if (west()) swapCornerContacts();
|
if (west()) swapCornerContacts();
|
||||||
|
|
||||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
|
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal, hDepth );
|
||||||
}
|
}
|
||||||
} else { // fields.globals == 4.
|
} else { // fields.globals == 4.
|
||||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||||
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal );
|
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal, hDepth );
|
||||||
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical );
|
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical , vDepth );
|
||||||
}
|
}
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
return true;
|
return true;
|
||||||
|
@ -490,16 +534,24 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << getTypeName() << "::_do_2G()" << endl;
|
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()) {
|
if (east() and west()) {
|
||||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||||
setNorthEastContact( 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()) {
|
} else if (south() and north()) {
|
||||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||||
setNorthEastContact( 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 {
|
} else {
|
||||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||||
}
|
}
|
||||||
|
@ -1568,7 +1620,7 @@ namespace Anabatic {
|
||||||
biggestRp = getRoutingPads()[i];
|
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()) {
|
if (east() and west() and not south() and not north()) {
|
||||||
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, HBothAccess );
|
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, HBothAccess );
|
||||||
|
@ -1580,6 +1632,7 @@ namespace Anabatic {
|
||||||
if (west() and not south()) {
|
if (west() and not south()) {
|
||||||
setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) );
|
setSouthWestContact( doRp_Access( getGCell(), getRoutingPads()[0], HAccess ) );
|
||||||
} else if (not west() and south()) {
|
} else if (not west() and south()) {
|
||||||
|
cdebug_log(145,1) << "case: not west and south" << endl;
|
||||||
setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
|
setSouthWestContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
|
||||||
} else if (west() and south()) {
|
} else if (west() and south()) {
|
||||||
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
|
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
|
||||||
|
@ -1590,6 +1643,7 @@ namespace Anabatic {
|
||||||
if (east() and not north()) {
|
if (east() and not north()) {
|
||||||
setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) );
|
setNorthEastContact( doRp_Access( getGCell(), getRoutingPads()[getRoutingPads().size()-1], HAccess ) );
|
||||||
} else if (not east() and north()) {
|
} else if (not east() and north()) {
|
||||||
|
cdebug_log(145,1) << "case: not east and north" << endl;
|
||||||
setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
|
setNorthEastContact( doRp_Access( getGCell(), biggestRp, NoFlags ) );
|
||||||
} else if (east() and north()) {
|
} else if (east() and north()) {
|
||||||
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
|
AutoContact* rpContact = doRp_Access( getGCell(), biggestRp, NoFlags );
|
||||||
|
@ -1605,6 +1659,7 @@ namespace Anabatic {
|
||||||
bool NetBuilderHV::_do_1G_1M3 ()
|
bool NetBuilderHV::_do_1G_1M3 ()
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M3() [Optimised Configuration]" << endl;
|
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;
|
uint64_t flags = (east() or west()) ? HAccess : NoFlags;
|
||||||
flags |= (north()) ? DoTargetContact : NoFlags;
|
flags |= (north()) ? DoTargetContact : NoFlags;
|
||||||
|
@ -1622,6 +1677,13 @@ namespace Anabatic {
|
||||||
cdebug_log(145,0) << "_southWest: " << getSouthWestContact() << endl;
|
cdebug_log(145,0) << "_southWest: " << getSouthWestContact() << endl;
|
||||||
cdebug_log(145,0) << "_northEast: " << getNorthEastContact() << 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);
|
const Layer* viaLayer1 = Session::getContactLayer(1);
|
||||||
|
|
||||||
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
Box cellAb = getAnabatic()->getCell()->getAbutmentBox();
|
||||||
|
@ -1658,6 +1720,7 @@ namespace Anabatic {
|
||||||
setBothCornerContacts( turn2 );
|
setBothCornerContacts( turn2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1665,9 +1728,28 @@ namespace Anabatic {
|
||||||
|
|
||||||
bool NetBuilderHV::_do_xG_xM3 ()
|
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()
|
cdebug_log(145,1) << getTypeName()
|
||||||
<< "::_do_xG_" << (int)getConnexity().fields.M3
|
<< "::_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) << "west:" << west() << endl;
|
||||||
cdebug_log(145,0) << "east:" << east() << endl;
|
cdebug_log(145,0) << "east:" << east() << endl;
|
||||||
cdebug_log(145,0) << "south:" << south() << endl;
|
cdebug_log(145,0) << "south:" << south() << endl;
|
||||||
|
@ -1678,7 +1760,6 @@ namespace Anabatic {
|
||||||
doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
|
doRp_StairCaseV( getGCell(), getRoutingPads()[i-1], getRoutingPads()[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
const Layer* viaLayer1 = Session::getContactLayer(1);
|
|
||||||
AutoContact* unusedContact = NULL;
|
AutoContact* unusedContact = NULL;
|
||||||
Component* rp = getRoutingPads()[0];
|
Component* rp = getRoutingPads()[0];
|
||||||
|
|
||||||
|
@ -1691,18 +1772,18 @@ namespace Anabatic {
|
||||||
cdebug_log(149,0) << "Misaligned South: _source:" << DbU::getValueString(getSourceContact()->getX())
|
cdebug_log(149,0) << "Misaligned South: _source:" << DbU::getValueString(getSourceContact()->getX())
|
||||||
<< "_southWest:" << DbU::getValueString(getSouthWestContact()->getX()) << endl;
|
<< "_southWest:" << DbU::getValueString(getSouthWestContact()->getX()) << endl;
|
||||||
|
|
||||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||||
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical );
|
AutoSegment::create( getSouthWestContact(), turn1, Flags::Vertical , vDepth );
|
||||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
|
AutoSegment::create( turn1 , turn2, Flags::Horizontal, hDepth );
|
||||||
setSouthWestContact( turn2 );
|
setSouthWestContact( turn2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (west() and south()) {
|
} else if (west() and south()) {
|
||||||
AutoContact* rpContact = NULL;
|
AutoContact* rpContact = NULL;
|
||||||
doRp_AutoContacts( getGCell(), rp, rpContact, unusedContact, DoSourceContact );
|
doRp_AutoContacts( getGCell(), rp, rpContact, unusedContact, DoSourceContact );
|
||||||
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
setSouthWestContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||||
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical );
|
AutoSegment::create( rpContact, getSouthWestContact(), Flags::Vertical, vDepth );
|
||||||
}
|
}
|
||||||
|
|
||||||
rp = getRoutingPads()[getRoutingPads().size()-1];
|
rp = getRoutingPads()[getRoutingPads().size()-1];
|
||||||
|
@ -1715,18 +1796,102 @@ namespace Anabatic {
|
||||||
cdebug_log(149,0) << "Misaligned North: _source:" << DbU::getValueString(getSourceContact()->getX())
|
cdebug_log(149,0) << "Misaligned North: _source:" << DbU::getValueString(getSourceContact()->getX())
|
||||||
<< "_southWest:" << DbU::getValueString(getNorthEastContact()->getX()) << endl;
|
<< "_southWest:" << DbU::getValueString(getNorthEastContact()->getX()) << endl;
|
||||||
|
|
||||||
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
AutoContactTurn* turn1 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||||
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 );
|
AutoContactTurn* turn2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||||
AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical );
|
AutoSegment::create( getNorthEastContact(), turn1, Flags::Vertical , vDepth );
|
||||||
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
|
AutoSegment::create( turn1 , turn2, Flags::Horizontal, hDepth );
|
||||||
setNorthEastContact( turn2 );
|
setNorthEastContact( turn2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (east() and north()) {
|
} else if (east() and north()) {
|
||||||
AutoContact* rpContact = NULL;
|
AutoContact* rpContact = NULL;
|
||||||
doRp_AutoContacts( getGCell(), rp, unusedContact, rpContact, DoTargetContact );
|
doRp_AutoContacts( getGCell(), rp, unusedContact, rpContact, DoTargetContact );
|
||||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ) );
|
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||||
AutoSegment::create( rpContact, getNorthEastContact(), Flags::Vertical );
|
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);
|
cdebug_tabw(145,-1);
|
||||||
|
@ -1737,6 +1902,8 @@ namespace Anabatic {
|
||||||
bool NetBuilderHV::_do_globalSegment ()
|
bool NetBuilderHV::_do_globalSegment ()
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
|
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
|
||||||
|
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
|
||||||
|
<< " getFlags():" << getFlags() << endl;
|
||||||
|
|
||||||
if (getSourceContact()) {
|
if (getSourceContact()) {
|
||||||
AutoContact* targetContact
|
AutoContact* targetContact
|
||||||
|
@ -1744,7 +1911,16 @@ namespace Anabatic {
|
||||||
? getNorthEastContact() : getSouthWestContact() ;
|
? getNorthEastContact() : getSouthWestContact() ;
|
||||||
if (not getFromHook()) cerr << "getFromHook() is NULL !" << endl;
|
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()
|
AutoSegment* globalSegment = AutoSegment::create( getSourceContact()
|
||||||
, targetContact
|
, targetContact
|
||||||
, baseSegment
|
, baseSegment
|
||||||
|
|
|
@ -85,7 +85,6 @@ namespace Anabatic {
|
||||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||||
Flags direction = Session::getDirection ( rpDepth );
|
Flags direction = Session::getDirection ( rpDepth );
|
||||||
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
|
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
|
||||||
DbU::Unit gridPosition = 0;
|
|
||||||
|
|
||||||
getPositions( rp, sourcePosition, targetPosition );
|
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.
|
// 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 );
|
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||||
if (irp == getRpLookup().end()) {
|
if (irp == getRpLookup().end()) {
|
||||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
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) {
|
if (not source and not target) {
|
||||||
source = target = AutoContactTerminal::create( gcell
|
source = target = AutoContactTerminal::create( gcell
|
||||||
, rp
|
, rp
|
||||||
|
@ -223,28 +178,43 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
|
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
|
||||||
|
|
||||||
AutoContact* rpContactSource;
|
AutoContact* rpContactSource = NULL;
|
||||||
AutoContact* rpContactTarget;
|
AutoContact* rpContactTarget = NULL;
|
||||||
|
const Layer* rpLayer = rp->getLayer();
|
||||||
|
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||||
|
|
||||||
flags |= checkRoutingPadSize( rp );
|
flags |= checkRoutingPadSize( rp );
|
||||||
|
|
||||||
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
|
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
|
||||||
|
|
||||||
if (not (flags & (HAccess|HAccessEW))) {
|
if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3).
|
||||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
if (not (flags & (HAccess|HAccessEW))) {
|
||||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 );
|
||||||
rpContactSource = subContact2;
|
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
|
||||||
} else {
|
rpContactSource = subContact2;
|
||||||
if (flags & VSmall) {
|
} 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;
|
AutoContact* subContact1 = NULL;
|
||||||
if (flags & HAccessEW)
|
if (flags & HAccessEW)
|
||||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||||
else
|
else
|
||||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||||
|
|
||||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical, rpDepth+1 );
|
||||||
rpContactSource = subContact1;
|
rpContactSource = subContact1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,7 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
|
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
|
||||||
|
|
||||||
|
_anabatic->disableCanonize();
|
||||||
for ( Net* net : _netInvalidateds ) {
|
for ( Net* net : _netInvalidateds ) {
|
||||||
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl;
|
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl;
|
||||||
_anabatic->updateNetTopology ( net );
|
_anabatic->updateNetTopology ( net );
|
||||||
|
@ -222,6 +223,7 @@ namespace Anabatic {
|
||||||
_anabatic->_computeNetOptimals ( net );
|
_anabatic->_computeNetOptimals ( net );
|
||||||
//_anabatic->_computeNetTerminals ( net );
|
//_anabatic->_computeNetTerminals ( net );
|
||||||
}
|
}
|
||||||
|
_anabatic->enableCanonize();
|
||||||
_canonize ();
|
_canonize ();
|
||||||
|
|
||||||
AutoSegment* segment = NULL;
|
AutoSegment* segment = NULL;
|
||||||
|
|
|
@ -204,6 +204,7 @@ namespace Anabatic {
|
||||||
public:
|
public:
|
||||||
static AnabaticEngine* create ( Cell* );
|
static AnabaticEngine* create ( Cell* );
|
||||||
static AnabaticEngine* get ( const Cell* );
|
static AnabaticEngine* get ( const Cell* );
|
||||||
|
inline bool isCanonizeDisabled () const;
|
||||||
static const Name& staticGetName ();
|
static const Name& staticGetName ();
|
||||||
virtual const Name& getName () const;
|
virtual const Name& getName () const;
|
||||||
virtual Configuration* getConfiguration ();
|
virtual Configuration* getConfiguration ();
|
||||||
|
@ -227,6 +228,8 @@ namespace Anabatic {
|
||||||
virtual void openSession ();
|
virtual void openSession ();
|
||||||
inline void setState ( EngineState state );
|
inline void setState ( EngineState state );
|
||||||
inline void setDensityMode ( uint64_t );
|
inline void setDensityMode ( uint64_t );
|
||||||
|
inline void disableCanonize ();
|
||||||
|
inline void enableCanonize ();
|
||||||
inline void addOv ( Edge* );
|
inline void addOv ( Edge* );
|
||||||
inline void removeOv ( Edge* );
|
inline void removeOv ( Edge* );
|
||||||
inline const NetDatas& getNetDatas () const;
|
inline const NetDatas& getNetDatas () const;
|
||||||
|
@ -380,6 +383,7 @@ namespace Anabatic {
|
||||||
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
|
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
|
||||||
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
|
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
|
||||||
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
|
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::isInDemoMode () const { return _flags & Flags::DemoMode; }
|
||||||
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
|
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
|
||||||
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); }
|
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::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
|
||||||
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
|
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
|
||||||
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
|
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 )
|
inline void AnabaticEngine::_add ( GCell* gcell )
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,11 +14,9 @@
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
#ifndef ANABATIC_AUTOHORIZONTAL_H
|
#pragma once
|
||||||
#define ANABATIC_AUTOHORIZONTAL_H
|
#include "hurricane/Horizontal.h"
|
||||||
|
#include "anabatic/AutoSegment.h"
|
||||||
#include "hurricane/Horizontal.h"
|
|
||||||
#include "anabatic/AutoSegment.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Anabatic {
|
namespace Anabatic {
|
||||||
|
@ -91,6 +89,3 @@ namespace Anabatic {
|
||||||
|
|
||||||
|
|
||||||
INSPECTOR_P_SUPPORT(Anabatic::AutoHorizontal);
|
INSPECTOR_P_SUPPORT(Anabatic::AutoHorizontal);
|
||||||
|
|
||||||
|
|
||||||
#endif // ANABATIC_AUTOHORIZONTAL_H
|
|
||||||
|
|
|
@ -216,7 +216,6 @@ namespace Anabatic {
|
||||||
inline bool isSpinBottom () const;
|
inline bool isSpinBottom () const;
|
||||||
inline bool isSpinTopOrBottom () const;
|
inline bool isSpinTopOrBottom () const;
|
||||||
inline bool isReduced () const;
|
inline bool isReduced () const;
|
||||||
bool isUnderMinLength () const;
|
|
||||||
inline bool isStrap () const;
|
inline bool isStrap () const;
|
||||||
inline bool isDogleg () const;
|
inline bool isDogleg () const;
|
||||||
inline bool isUnbound () const;
|
inline bool isUnbound () const;
|
||||||
|
@ -227,7 +226,7 @@ namespace Anabatic {
|
||||||
inline bool isUnsetAxis () const;
|
inline bool isUnsetAxis () const;
|
||||||
inline bool isSlackened () const;
|
inline bool isSlackened () const;
|
||||||
inline bool isUserDefined () const;
|
inline bool isUserDefined () const;
|
||||||
bool isMiddleStack () const;
|
bool isNearMinArea () const;
|
||||||
bool isReduceCandidate () const;
|
bool isReduceCandidate () const;
|
||||||
bool isUTurn () const;
|
bool isUTurn () const;
|
||||||
inline bool isAnalog () const;
|
inline bool isAnalog () const;
|
||||||
|
@ -340,8 +339,8 @@ namespace Anabatic {
|
||||||
bool bloatStackedStrap ();
|
bool bloatStackedStrap ();
|
||||||
bool reduce ( Flags flags=Flags::WithPerpands );
|
bool reduce ( Flags flags=Flags::WithPerpands );
|
||||||
bool raise ();
|
bool raise ();
|
||||||
bool expandToMinLength ( Interval );
|
void expandToMinLength ( Interval );
|
||||||
bool unexpandToMinLength ();
|
void unexpandToMinLength ();
|
||||||
// Canonical Modifiers.
|
// Canonical Modifiers.
|
||||||
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||||
virtual void invalidate ( Flags flags=Flags::Propagate );
|
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||||
|
|
|
@ -14,11 +14,9 @@
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
#ifndef ANABATIC_AUTOVERTICAL_H
|
#pragma once
|
||||||
#define ANABATIC_AUTOVERTICAL_H
|
#include "hurricane/Vertical.h"
|
||||||
|
#include "anabatic/AutoSegment.h"
|
||||||
#include "hurricane/Vertical.h"
|
|
||||||
#include "anabatic/AutoSegment.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace Anabatic {
|
namespace Anabatic {
|
||||||
|
@ -91,6 +89,3 @@ namespace Anabatic {
|
||||||
|
|
||||||
|
|
||||||
INSPECTOR_P_SUPPORT(Anabatic::AutoVertical);
|
INSPECTOR_P_SUPPORT(Anabatic::AutoVertical);
|
||||||
|
|
||||||
|
|
||||||
#endif // ANABATIC_AUTOHORIZONTAL_H
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ namespace Anabatic {
|
||||||
static const BaseFlags DestroyGCell ; // = (1 << 7);
|
static const BaseFlags DestroyGCell ; // = (1 << 7);
|
||||||
static const BaseFlags DestroyBaseContact ; // = (1 << 8);
|
static const BaseFlags DestroyBaseContact ; // = (1 << 8);
|
||||||
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
|
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
|
||||||
|
static const BaseFlags DisableCanonize ; // = (1 << 10);
|
||||||
// Flags for NetDatas objects states only.
|
// Flags for NetDatas objects states only.
|
||||||
static const BaseFlags GlobalFixed ; // = (1 << 5);
|
static const BaseFlags GlobalFixed ; // = (1 << 5);
|
||||||
static const BaseFlags GlobalEstimated ; // = (1 << 6);
|
static const BaseFlags GlobalEstimated ; // = (1 << 6);
|
||||||
|
|
|
@ -259,6 +259,7 @@ namespace Anabatic {
|
||||||
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
|
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
|
||||||
void setType ( Flags );
|
void setType ( Flags );
|
||||||
inline void setSatProcessed ( size_t depth );
|
inline void setSatProcessed ( size_t depth );
|
||||||
|
void postGlobalAnnotate ();
|
||||||
void addBlockage ( size_t depth, DbU::Unit );
|
void addBlockage ( size_t depth, DbU::Unit );
|
||||||
inline void addHSegment ( AutoSegment* );
|
inline void addHSegment ( AutoSegment* );
|
||||||
inline void addVSegment ( AutoSegment* );
|
inline void addVSegment ( AutoSegment* );
|
||||||
|
|
|
@ -47,31 +47,39 @@ namespace Anabatic {
|
||||||
|
|
||||||
class ForkStack {
|
class ForkStack {
|
||||||
public:
|
public:
|
||||||
inline void push ( Hook* from, AutoContact* contact );
|
inline void push ( Hook* from, AutoContact* contact, uint64_t flags );
|
||||||
inline void pop ();
|
inline void pop ();
|
||||||
inline Hook* getFrom () const;
|
inline Hook* getFrom () const;
|
||||||
inline AutoContact* getContact () const;
|
inline AutoContact* getContact () const;
|
||||||
|
inline uint64_t getFlags () const;
|
||||||
|
inline void setFlags ( uint64_t );
|
||||||
private:
|
private:
|
||||||
struct Element {
|
struct Element {
|
||||||
Hook* _from;
|
Hook* _from;
|
||||||
AutoContact* _contact;
|
AutoContact* _contact;
|
||||||
inline Element ( Hook* from, AutoContact* contact );
|
uint64_t _flags;
|
||||||
|
inline Element ( Hook* from, AutoContact* contact, uint64_t flags );
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
list<Element> _stack;
|
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 void ForkStack::pop () { if (not _stack.empty()) _stack.pop_back(); }
|
||||||
inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; }
|
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 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;
|
cdebug_log(145,0) << " Stacking: " << endl;
|
||||||
_stack.push_back( Element(from,contact) );
|
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)
|
, Middle = (1 << 16)
|
||||||
, UseNonPref = (1 << 17)
|
, UseNonPref = (1 << 17)
|
||||||
, NoProtect = (1 << 18)
|
, NoProtect = (1 << 18)
|
||||||
|
, ToUpperRouting = (1 << 19)
|
||||||
, HBothAccess = HAccess|HAccessEW
|
, HBothAccess = HAccess|HAccessEW
|
||||||
, SouthWest = SouthBound|WestBound
|
, SouthWest = SouthBound|WestBound
|
||||||
, NorthEast = NorthBound|EastBound
|
, NorthEast = NorthBound|EastBound
|
||||||
|
@ -149,13 +158,15 @@ namespace Anabatic {
|
||||||
virtual ~NetBuilder ();
|
virtual ~NetBuilder ();
|
||||||
void clear ();
|
void clear ();
|
||||||
inline bool isTwoMetals () const;
|
inline bool isTwoMetals () const;
|
||||||
|
inline bool isUpperMetalRp () const;
|
||||||
inline AnabaticEngine* getAnabatic () const;
|
inline AnabaticEngine* getAnabatic () const;
|
||||||
inline unsigned int getDegree () const;
|
inline unsigned int getDegree () const;
|
||||||
inline void setDegree ( unsigned int degree );
|
inline void setDegree ( unsigned int degree );
|
||||||
void fixSegments ();
|
void fixSegments ();
|
||||||
NetBuilder& setStartHook ( AnabaticEngine*
|
NetBuilder& setStartHook ( AnabaticEngine*
|
||||||
, Hook* fromHook
|
, Hook* fromHook
|
||||||
, AutoContact* sourceContact=NULL );
|
, AutoContact* sourceContact=NULL
|
||||||
|
, uint64_t sourceFlags=0 );
|
||||||
void construct ();
|
void construct ();
|
||||||
inline unsigned int getStateG () const;
|
inline unsigned int getStateG () const;
|
||||||
inline UConnexity getConnexity () const;
|
inline UConnexity getConnexity () const;
|
||||||
|
@ -169,6 +180,8 @@ namespace Anabatic {
|
||||||
inline AutoContact* getNorthEastContact () const;
|
inline AutoContact* getNorthEastContact () const;
|
||||||
inline AutoContact*& getNorthEastContact ();
|
inline AutoContact*& getNorthEastContact ();
|
||||||
inline Hook* getFromHook () const;
|
inline Hook* getFromHook () const;
|
||||||
|
inline uint64_t getSourceFlags () const;
|
||||||
|
inline uint64_t getFlags () const;
|
||||||
inline ForkStack& getForks ();
|
inline ForkStack& getForks ();
|
||||||
inline vector<RoutingPad*>& getRoutingPads ();
|
inline vector<RoutingPad*>& getRoutingPads ();
|
||||||
inline map<Component*,AutoSegment*>& getRpLookup ();
|
inline map<Component*,AutoSegment*>& getRpLookup ();
|
||||||
|
@ -187,6 +200,7 @@ namespace Anabatic {
|
||||||
inline void clearSouths ();
|
inline void clearSouths ();
|
||||||
inline void clearEasts ();
|
inline void clearEasts ();
|
||||||
inline void clearWests ();
|
inline void clearWests ();
|
||||||
|
inline void setFlags ( uint64_t );
|
||||||
inline void setFromHook ( Hook* );
|
inline void setFromHook ( Hook* );
|
||||||
inline void setSouthWestContact ( AutoContact* );
|
inline void setSouthWestContact ( AutoContact* );
|
||||||
inline void setNorthEastContact ( AutoContact* );
|
inline void setNorthEastContact ( AutoContact* );
|
||||||
|
@ -194,6 +208,7 @@ namespace Anabatic {
|
||||||
inline void swapCornerContacts ();
|
inline void swapCornerContacts ();
|
||||||
inline void addToFixSegments ( AutoSegment* );
|
inline void addToFixSegments ( AutoSegment* );
|
||||||
bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 );
|
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 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_Access ( GCell*, Component*, uint64_t flags ) = 0;
|
||||||
virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags );
|
virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags );
|
||||||
|
@ -372,9 +387,8 @@ namespace Anabatic {
|
||||||
vector<AutoSegment*> _toFixSegments;
|
vector<AutoSegment*> _toFixSegments;
|
||||||
unsigned int _degree;
|
unsigned int _degree;
|
||||||
bool _isTwoMetals;
|
bool _isTwoMetals;
|
||||||
|
uint64_t _sourceFlags;
|
||||||
// Sort classes.
|
uint64_t _flags;
|
||||||
public:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,6 +408,8 @@ namespace Anabatic {
|
||||||
inline AutoContact* NetBuilder::getNorthEastContact () const { return _northEastContact; }
|
inline AutoContact* NetBuilder::getNorthEastContact () const { return _northEastContact; }
|
||||||
inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; }
|
inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; }
|
||||||
inline Hook* NetBuilder::getFromHook () const { return _fromHook; }
|
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 unsigned int NetBuilder::getTopology () const { return _topology; }
|
||||||
inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; }
|
inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; }
|
||||||
inline map<Component*,AutoSegment*>& NetBuilder::getRpLookup () { return _routingPadAutoSegments; }
|
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::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::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 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::setDegree ( unsigned int degree ) { _degree = degree; }
|
||||||
inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; }
|
inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; }
|
||||||
inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; }
|
inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; }
|
||||||
|
|
|
@ -13,9 +13,7 @@
|
||||||
// | C++ Header : "./anabatic/NetBuilderHV.h" |
|
// | C++ Header : "./anabatic/NetBuilderHV.h" |
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
#ifndef ANABATIC_NET_BUILDER_HV_H
|
#pragma once
|
||||||
#define ANABATIC_NET_BUILDER_HV_H
|
|
||||||
|
|
||||||
#include "anabatic/NetBuilder.h"
|
#include "anabatic/NetBuilder.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,44 +26,44 @@ namespace Anabatic {
|
||||||
|
|
||||||
class NetBuilderHV : public NetBuilder {
|
class NetBuilderHV : public NetBuilder {
|
||||||
public:
|
public:
|
||||||
NetBuilderHV ();
|
NetBuilderHV ();
|
||||||
virtual ~NetBuilderHV ();
|
virtual ~NetBuilderHV ();
|
||||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||||
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
|
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
|
||||||
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
||||||
private:
|
private:
|
||||||
virtual bool _do_1G_1M1 ();
|
virtual bool _do_1G_1M1 ();
|
||||||
virtual bool _do_1G_xM1 ();
|
virtual bool _do_1G_xM1 ();
|
||||||
virtual bool _do_xG ();
|
virtual bool _do_xG ();
|
||||||
virtual bool _do_2G ();
|
virtual bool _do_2G ();
|
||||||
virtual bool _do_2G_1M1 ();
|
virtual bool _do_2G_1M1 ();
|
||||||
virtual bool _do_xG_1Pad ();
|
virtual bool _do_xG_1Pad ();
|
||||||
virtual bool _do_1G_1PinM1 ();
|
virtual bool _do_1G_1PinM1 ();
|
||||||
virtual bool _do_2G_1PinM1 ();
|
virtual bool _do_2G_1PinM1 ();
|
||||||
virtual bool _do_1G_1PinM2 ();
|
virtual bool _do_1G_1PinM2 ();
|
||||||
virtual bool _do_xG_1PinM2 ();
|
virtual bool _do_xG_1PinM2 ();
|
||||||
virtual bool _do_1G_1PinM3 ();
|
virtual bool _do_1G_1PinM3 ();
|
||||||
virtual bool _do_xG_1PinM3 ();
|
virtual bool _do_xG_1PinM3 ();
|
||||||
virtual bool _do_xG_1M1 ();
|
virtual bool _do_xG_1M1 ();
|
||||||
virtual bool _do_xG_1M1_1M2 ();
|
virtual bool _do_xG_1M1_1M2 ();
|
||||||
virtual bool _do_xG_xM1_xM3 ();
|
virtual bool _do_xG_xM1_xM3 ();
|
||||||
virtual bool _do_4G_1M2 ();
|
virtual bool _do_4G_1M2 ();
|
||||||
virtual bool _do_xG_xM2 ();
|
virtual bool _do_xG_xM2 ();
|
||||||
virtual bool _do_1G_1M3 ();
|
virtual bool _do_1G_1M3 ();
|
||||||
virtual bool _do_xG_xM3 ();
|
virtual bool _do_xG_xM3 ();
|
||||||
virtual bool _do_1G_xM1_1PinM2 ();
|
bool _do_xG_xM3_baseRouting ();
|
||||||
virtual bool _do_2G_xM1_1PinM2 ();
|
bool _do_xG_xM3_upperRouting ();
|
||||||
virtual bool _do_1G_1M1_1PinM3 ();
|
virtual bool _do_1G_xM1_1PinM2 ();
|
||||||
virtual bool _do_2G_xM1_1PinM3 ();
|
virtual bool _do_2G_xM1_1PinM2 ();
|
||||||
virtual bool _do_3G_xM1_1PinM3 ();
|
virtual bool _do_1G_1M1_1PinM3 ();
|
||||||
virtual bool _do_globalSegment ();
|
virtual bool _do_2G_xM1_1PinM3 ();
|
||||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
virtual bool _do_3G_xM1_1PinM3 ();
|
||||||
public:
|
virtual bool _do_globalSegment ();
|
||||||
virtual string getTypeName () const;
|
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||||
|
public:
|
||||||
|
virtual string getTypeName () const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // Anabatic namespace.
|
} // Anabatic namespace.
|
||||||
|
|
||||||
#endif // ANABATIC_NET_BUILDER_HV_H
|
|
||||||
|
|
|
@ -13,9 +13,7 @@
|
||||||
// | C++ Header : "./anabatic/NetBuilderVH.h" |
|
// | C++ Header : "./anabatic/NetBuilderVH.h" |
|
||||||
// +-----------------------------------------------------------------+
|
// +-----------------------------------------------------------------+
|
||||||
|
|
||||||
#ifndef ANABATIC_NET_BUILDER_VH_H
|
#pragma once
|
||||||
#define ANABATIC_NET_BUILDER_VH_H
|
|
||||||
|
|
||||||
#include "anabatic/NetBuilder.h"
|
#include "anabatic/NetBuilder.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,5 +48,3 @@ namespace Anabatic {
|
||||||
|
|
||||||
|
|
||||||
} // Anabatic namespace.
|
} // Anabatic namespace.
|
||||||
|
|
||||||
#endif // ANABATIC_NET_BUILDER_VH_H
|
|
||||||
|
|
|
@ -825,7 +825,7 @@ namespace CRL {
|
||||||
|
|
||||||
CellGauge* AllianceFramework::matchCellGauge ( DbU::Unit width, DbU::Unit height ) const
|
CellGauge* AllianceFramework::matchCellGauge ( DbU::Unit width, DbU::Unit height ) const
|
||||||
{
|
{
|
||||||
for ( const auto item : _cellGauges ) {
|
for ( const auto& item : _cellGauges ) {
|
||||||
CellGauge* cg = item.second;
|
CellGauge* cg = item.second;
|
||||||
DbU::Unit hcount = width / cg->getSliceStep ();
|
DbU::Unit hcount = width / cg->getSliceStep ();
|
||||||
DbU::Unit hremains = width % cg->getSliceStep ();
|
DbU::Unit hremains = width % cg->getSliceStep ();
|
||||||
|
@ -842,7 +842,7 @@ namespace CRL {
|
||||||
|
|
||||||
CellGauge* AllianceFramework::matchCellGaugeByHeight ( DbU::Unit height ) const
|
CellGauge* AllianceFramework::matchCellGaugeByHeight ( DbU::Unit height ) const
|
||||||
{
|
{
|
||||||
for ( const auto item : _cellGauges ) {
|
for ( const auto& item : _cellGauges ) {
|
||||||
CellGauge* cg = item.second;
|
CellGauge* cg = item.second;
|
||||||
DbU::Unit vcount = height / cg->getSliceHeight();
|
DbU::Unit vcount = height / cg->getSliceHeight();
|
||||||
DbU::Unit vremains = height % cg->getSliceHeight();
|
DbU::Unit vremains = height % cg->getSliceHeight();
|
||||||
|
|
|
@ -56,20 +56,22 @@ namespace CRL {
|
||||||
|
|
||||||
|
|
||||||
RoutingGauge::RoutingGauge ( const char* name )
|
RoutingGauge::RoutingGauge ( const char* name )
|
||||||
: _name (name)
|
: _name (name)
|
||||||
, _layerGauges()
|
, _layerGauges ()
|
||||||
, _viaLayers ()
|
, _viaLayers ()
|
||||||
, _technology (DataBase::getDB()->getTechnology())
|
, _technology (DataBase::getDB()->getTechnology())
|
||||||
, _isSymbolic (true)
|
, _isSymbolic (true)
|
||||||
|
, _isSuperPitched(true)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
RoutingGauge::RoutingGauge ( const RoutingGauge& gauge )
|
RoutingGauge::RoutingGauge ( const RoutingGauge& gauge )
|
||||||
: _name (gauge._name)
|
: _name (gauge._name)
|
||||||
, _layerGauges()
|
, _layerGauges ()
|
||||||
, _viaLayers ()
|
, _viaLayers ()
|
||||||
, _technology (gauge._technology)
|
, _technology (gauge._technology)
|
||||||
, _isSymbolic (gauge._isSymbolic)
|
, _isSymbolic (gauge._isSymbolic)
|
||||||
|
, _isSuperPitched(gauge._isSuperPitched)
|
||||||
{
|
{
|
||||||
// Make a deep copy of the map.
|
// Make a deep copy of the map.
|
||||||
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ ) {
|
for ( size_t i=0 ; i<gauge._layerGauges.size() ; i++ ) {
|
||||||
|
@ -304,6 +306,12 @@ namespace CRL {
|
||||||
}
|
}
|
||||||
_viaLayers.push_back( viaLayer );
|
_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 );
|
Bit* bit = BitExtension::get( net );
|
||||||
if (bit) return bit;
|
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\"."
|
" In cell \"%s\"."
|
||||||
, getString(net).c_str()
|
, getString(net).c_str()
|
||||||
, getString(net->getCell()->getName()).c_str()
|
, getString(net->getCell()->getName()).c_str()
|
||||||
|
|
|
@ -854,12 +854,12 @@ association_element
|
||||||
<< " Port map assignment discrepency "
|
<< " Port map assignment discrepency "
|
||||||
<< "instance:" << Vst::states->_instanceNets.size()
|
<< "instance:" << Vst::states->_instanceNets.size()
|
||||||
<< " vs. model:" << Vst::states->_masterNets.size();
|
<< " vs. model:" << Vst::states->_masterNets.size();
|
||||||
message << "\nModel:";
|
message << "\nModel \"" << Vst::states->_instance->getMasterCell()->getName() << "\":";
|
||||||
for ( Net* net : Vst::states->_masterNets )
|
for ( Net* net : Vst::states->_masterNets )
|
||||||
message << " \"" << net->getName() << "\"";
|
message << "\n* \"" << net->getName() << "\"";
|
||||||
message << "\nInstance:";
|
message << "\nInstance " << Vst::states->_instance->getName() << "\":";
|
||||||
for ( Net* net : Vst::states->_instanceNets )
|
for ( Net* net : Vst::states->_instanceNets )
|
||||||
message << " \"" << net->getName() << "\"";
|
message << "\n* \"" << net->getName() << "\"";
|
||||||
throw Error( message.str() );
|
throw Error( message.str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -280,13 +280,15 @@ namespace {
|
||||||
void connectSubckts ();
|
void connectSubckts ();
|
||||||
Net* mergeNet ( string name, bool isExternal, unsigned int );
|
Net* mergeNet ( string name, bool isExternal, unsigned int );
|
||||||
Net* mergeAlias ( string name1, string name2 );
|
Net* mergeAlias ( string name1, string name2 );
|
||||||
|
Net* newDummyNet ();
|
||||||
private:
|
private:
|
||||||
Cell* _cell;
|
Cell* _cell;
|
||||||
Subckts _subckts;
|
Subckts _subckts;
|
||||||
size_t _depth;
|
size_t _depth;
|
||||||
size_t _supplyCount;
|
size_t _supplyCount;
|
||||||
Instance* _oneInstance;
|
Instance* _oneInstance;
|
||||||
Instance* _zeroInstance;
|
Instance* _zeroInstance;
|
||||||
|
vector<Net*> _dummyOutputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -482,6 +484,7 @@ namespace {
|
||||||
, _supplyCount (0)
|
, _supplyCount (0)
|
||||||
, _oneInstance (NULL)
|
, _oneInstance (NULL)
|
||||||
, _zeroInstance(NULL)
|
, _zeroInstance(NULL)
|
||||||
|
, _dummyOutputs()
|
||||||
{
|
{
|
||||||
if (not _staticInit) staticInit();
|
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 )
|
Net* Model::mergeNet ( string name, bool isExternal, unsigned int direction )
|
||||||
{
|
{
|
||||||
bool isClock = AllianceFramework::get()->isCLOCK( name );
|
bool isClock = AllianceFramework::get()->isCLOCK( name );
|
||||||
|
@ -766,6 +778,29 @@ namespace {
|
||||||
if (not message.str().empty()) cerr << Warning( message.str() ) << endl;
|
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
|
#pragma once
|
||||||
#define CRL_ROUTING_GAUGE_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "hurricane/Name.h"
|
#include "hurricane/Name.h"
|
||||||
|
@ -56,6 +54,7 @@ namespace CRL {
|
||||||
// Predicates.
|
// Predicates.
|
||||||
inline bool isSymbolic () const;
|
inline bool isSymbolic () const;
|
||||||
inline bool isTwoMetals () const;
|
inline bool isTwoMetals () const;
|
||||||
|
inline bool isSuperPitched () const;
|
||||||
inline bool isHV () const;
|
inline bool isHV () const;
|
||||||
inline bool isVH () const;
|
inline bool isVH () const;
|
||||||
inline bool hasPowerSupply () const;
|
inline bool hasPowerSupply () const;
|
||||||
|
@ -109,6 +108,7 @@ namespace CRL {
|
||||||
vector<Layer*> _viaLayers;
|
vector<Layer*> _viaLayers;
|
||||||
Technology* _technology;
|
Technology* _technology;
|
||||||
bool _isSymbolic;
|
bool _isSymbolic;
|
||||||
|
bool _isSuperPitched;
|
||||||
|
|
||||||
// Internal - Constructors & Destructors.
|
// Internal - Constructors & Destructors.
|
||||||
RoutingGauge ( const char* name );
|
RoutingGauge ( const char* name );
|
||||||
|
@ -120,6 +120,7 @@ namespace CRL {
|
||||||
|
|
||||||
|
|
||||||
inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; }
|
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::isTwoMetals () const { return (getDepth() < 3); }
|
||||||
inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
|
inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
|
||||||
inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
|
inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
|
||||||
|
@ -155,5 +156,3 @@ namespace CRL {
|
||||||
} // CRL namespace.
|
} // CRL namespace.
|
||||||
|
|
||||||
INSPECTOR_P_SUPPORT(CRL::RoutingGauge);
|
INSPECTOR_P_SUPPORT(CRL::RoutingGauge);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -88,15 +88,16 @@ namespace CRL {
|
||||||
if ( vhdlName.empty() and (isdigit(translated)) )
|
if ( vhdlName.empty() and (isdigit(translated)) )
|
||||||
vhdlName += 'n';
|
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 = '_';
|
||||||
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 = '_';
|
||||||
if (translated == ']' ) translated = rightPar;
|
if (translated == '[' ) translated = leftPar;
|
||||||
|
if (translated == ']' ) translated = rightPar;
|
||||||
|
|
||||||
if (translated == '_') {
|
if (translated == '_') {
|
||||||
if (vhdlName.empty() ) continue;
|
if (vhdlName.empty() ) continue;
|
||||||
|
|
|
@ -504,6 +504,7 @@ extern "C" {
|
||||||
GetNameMethod(RoutingGauge,rg)
|
GetNameMethod(RoutingGauge,rg)
|
||||||
accessorVectorFromVoid(getLayerGauges,PyRoutingGauge,RoutingGauge,RoutingLayerGauge)
|
accessorVectorFromVoid(getLayerGauges,PyRoutingGauge,RoutingGauge,RoutingLayerGauge)
|
||||||
DirectGetBoolAttribute(PyRoutingGauge_isSymbolic ,isSymbolic ,PyRoutingGauge,RoutingGauge)
|
DirectGetBoolAttribute(PyRoutingGauge_isSymbolic ,isSymbolic ,PyRoutingGauge,RoutingGauge)
|
||||||
|
DirectGetBoolAttribute(PyRoutingGauge_isSuperPitched,isSuperPitched,PyRoutingGauge,RoutingGauge)
|
||||||
DirectSetBoolAttribute(PyRoutingGauge_setSymbolic ,setSymbolic ,PyRoutingGauge,RoutingGauge)
|
DirectSetBoolAttribute(PyRoutingGauge_setSymbolic ,setSymbolic ,PyRoutingGauge,RoutingGauge)
|
||||||
DirectGetBoolAttribute(PyRoutingGauge_isHV ,isHV ,PyRoutingGauge,RoutingGauge)
|
DirectGetBoolAttribute(PyRoutingGauge_isHV ,isHV ,PyRoutingGauge,RoutingGauge)
|
||||||
DirectGetBoolAttribute(PyRoutingGauge_isVH ,isVH ,PyRoutingGauge,RoutingGauge)
|
DirectGetBoolAttribute(PyRoutingGauge_isVH ,isVH ,PyRoutingGauge,RoutingGauge)
|
||||||
|
@ -518,6 +519,8 @@ extern "C" {
|
||||||
, "Create a new RoutingGauge." }
|
, "Create a new RoutingGauge." }
|
||||||
, { "isSymbolic" , (PyCFunction)PyRoutingGauge_isSymbolic , METH_NOARGS
|
, { "isSymbolic" , (PyCFunction)PyRoutingGauge_isSymbolic , METH_NOARGS
|
||||||
, "The RoutingGauge is for symbolic technology." }
|
, "The RoutingGauge is for symbolic technology." }
|
||||||
|
, { "isSuperPitched" , (PyCFunction)PyRoutingGauge_isSuperPitched , METH_NOARGS
|
||||||
|
, "The RoutingGauge is super-pitched." }
|
||||||
, { "isHV" , (PyCFunction)PyRoutingGauge_isHV , METH_NOARGS
|
, { "isHV" , (PyCFunction)PyRoutingGauge_isHV , METH_NOARGS
|
||||||
, "The first routing layer (metal2) is horizontal." }
|
, "The first routing layer (metal2) is horizontal." }
|
||||||
, { "isVH" , (PyCFunction)PyRoutingGauge_isVH , METH_NOARGS
|
, { "isVH" , (PyCFunction)PyRoutingGauge_isVH , METH_NOARGS
|
||||||
|
|
|
@ -673,7 +673,9 @@ class Block ( object ):
|
||||||
self.initEtesian()
|
self.initEtesian()
|
||||||
if self.conf.placeArea:
|
if self.conf.placeArea:
|
||||||
self.etesian.setPlaceArea( 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()
|
self.etesian.place()
|
||||||
Breakpoint.stop( 100, 'Placement done.' )
|
Breakpoint.stop( 100, 'Placement done.' )
|
||||||
self.etesian.clearColoquinte()
|
self.etesian.clearColoquinte()
|
||||||
|
|
|
@ -1186,7 +1186,12 @@ class IoPin ( object ):
|
||||||
self.stem = stem
|
self.stem = stem
|
||||||
self.upos = upos
|
self.upos = upos
|
||||||
self.ustep = ustep
|
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):
|
if self.upos == 0 and not (self.flags & IoPin.A_MASK):
|
||||||
raise ErrorMessage( 1, [ 'IoPin.__init__(): "upos" parameter cannot be zero, corners are forbidden.'
|
raise ErrorMessage( 1, [ 'IoPin.__init__(): "upos" parameter cannot be zero, corners are forbidden.'
|
||||||
, 'For net "{}"'.format(stem) ] )
|
, '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.'
|
raise ErrorMessage( 1, [ 'IoPin.__init__(): "ustep" parameter cannot be zero when "count" more than 1.'
|
||||||
, 'For net "{}"'.format(stem) ] )
|
, 'For net "{}"'.format(stem) ] )
|
||||||
|
|
||||||
@property
|
|
||||||
def indexes ( self ):
|
|
||||||
if isinstance(self.count,int):
|
|
||||||
return range(self.count)
|
|
||||||
return self.count
|
|
||||||
|
|
||||||
# def place ( self, block ):
|
# def place ( self, block ):
|
||||||
# """
|
# """
|
||||||
# Performs the actual creation of the Pin. Should be called prior to any
|
# 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 )
|
left1X = gaugeConf.getNearestVerticalTrack( tl1Contact.getX(), 0, 0 )
|
||||||
left1Y = gaugeConf.getStackY( contact, GaugeConf.DeepDepth )
|
left1Y = gaugeConf.getStackY( contact, GaugeConf.DeepDepth )
|
||||||
dxLeft = contact.getX() - gaugeConf.getStackX( 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.expandMinArea( tl2Contact )
|
||||||
gaugeConf.setStackPosition( tl1Contact, left1X , left1Y )
|
|
||||||
#gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth|GaugeConf.SourceExtend )
|
#gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth|GaugeConf.SourceExtend )
|
||||||
gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth, dxLeft )
|
gaugeConf.createHorizontal( contact , tl1Contact, left1Y , GaugeConf.DeepDepth, dxLeft )
|
||||||
gaugeConf.createVertical ( contact , tl2Contact, x, 0 )
|
gaugeConf.createVertical ( contact , tl2Contact, x, 0 )
|
||||||
|
|
|
@ -144,9 +144,9 @@ class Chip ( Block ):
|
||||||
self.conf.refresh()
|
self.conf.refresh()
|
||||||
|
|
||||||
def doPnR ( self ):
|
def doPnR ( self ):
|
||||||
super(Chip,self).doPnR()
|
status = super(Chip,self).doPnR()
|
||||||
self.conf.refresh( self.conf.chip )
|
self.conf.refresh( self.conf.chip )
|
||||||
return self.conf.validated
|
return self.conf.validated and status
|
||||||
|
|
||||||
def save ( self, flags=0 ):
|
def save ( self, flags=0 ):
|
||||||
if not self.conf.validated:
|
if not self.conf.validated:
|
||||||
|
|
|
@ -29,6 +29,9 @@ except Exception as e:
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
|
|
||||||
|
saveds = set()
|
||||||
|
|
||||||
|
|
||||||
def rsave ( cell, views=CRL.Catalog.State.Physical, depth=0, enableSpice=False ):
|
def rsave ( cell, views=CRL.Catalog.State.Physical, depth=0, enableSpice=False ):
|
||||||
"""
|
"""
|
||||||
Write back layout to disk if everything has gone fine.
|
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
|
of abutment box for placement, the netlist view must also
|
||||||
be saved.
|
be saved.
|
||||||
"""
|
"""
|
||||||
|
global saveds
|
||||||
|
|
||||||
|
if depth == 0: saveds.clear()
|
||||||
|
if cell in saveds: return
|
||||||
|
saveds.add( cell )
|
||||||
|
|
||||||
framework = CRL.AllianceFramework.get()
|
framework = CRL.AllianceFramework.get()
|
||||||
if depth == 0: print( ' o Recursive Save-Cell.' )
|
if depth == 0: print( ' o Recursive Save-Cell.' )
|
||||||
if cell.isUniquified(): views |= CRL.Catalog.State.Logical
|
if cell.isUniquified(): views |= CRL.Catalog.State.Logical
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace Etesian {
|
||||||
using Hurricane::tab;
|
using Hurricane::tab;
|
||||||
using Hurricane::Warning;
|
using Hurricane::Warning;
|
||||||
using Hurricane::Error;
|
using Hurricane::Error;
|
||||||
|
using Hurricane::DebugSession;
|
||||||
using Hurricane::Path;
|
using Hurricane::Path;
|
||||||
using Hurricane::Transformation;
|
using Hurricane::Transformation;
|
||||||
using Hurricane::DataBase;
|
using Hurricane::DataBase;
|
||||||
|
@ -249,6 +250,7 @@ namespace Etesian {
|
||||||
|
|
||||||
void Cluster::splitNet ()
|
void Cluster::splitNet ()
|
||||||
{
|
{
|
||||||
|
cdebug_log(123,0) << "Cluster::splitNet()" << endl;
|
||||||
createOutput();
|
createOutput();
|
||||||
for ( Cluster* cluster : _clusters ) {
|
for ( Cluster* cluster : _clusters ) {
|
||||||
cluster->createInput( _driverNet );
|
cluster->createInput( _driverNet );
|
||||||
|
@ -291,10 +293,10 @@ namespace Etesian {
|
||||||
virtual void splitNet ();
|
virtual void splitNet ();
|
||||||
void rpartition ();
|
void rpartition ();
|
||||||
uint32_t build ();
|
uint32_t build ();
|
||||||
|
bool rcleanupNet ( Net* );
|
||||||
string _getTypeName () const;
|
string _getTypeName () const;
|
||||||
private:
|
private:
|
||||||
SubNetNames _subNetNames;
|
SubNetNames _subNetNames;
|
||||||
bool _isDeepNet;
|
|
||||||
Net* _rootNet;
|
Net* _rootNet;
|
||||||
RoutingPad* _rpDriver;
|
RoutingPad* _rpDriver;
|
||||||
vector< vector<Cluster*> > _clustersStack;
|
vector< vector<Cluster*> > _clustersStack;
|
||||||
|
@ -304,7 +306,6 @@ namespace Etesian {
|
||||||
BufferTree::BufferTree ( EtesianEngine* etesian, Net* rootNet )
|
BufferTree::BufferTree ( EtesianEngine* etesian, Net* rootNet )
|
||||||
: Cluster(etesian)
|
: Cluster(etesian)
|
||||||
, _subNetNames ()
|
, _subNetNames ()
|
||||||
, _isDeepNet (true)
|
|
||||||
, _rootNet (rootNet)
|
, _rootNet (rootNet)
|
||||||
, _rpDriver (NULL)
|
, _rpDriver (NULL)
|
||||||
, _clustersStack()
|
, _clustersStack()
|
||||||
|
@ -331,14 +332,18 @@ namespace Etesian {
|
||||||
|
|
||||||
void BufferTree::splitNet ()
|
void BufferTree::splitNet ()
|
||||||
{
|
{
|
||||||
|
cdebug_log(123,0) << "BufferTree::splitNet()" << endl;
|
||||||
if (not _rpDriver)
|
if (not _rpDriver)
|
||||||
throw Error( "BufferTree::splitNet(): Missing driver on %s.", getString(_rootNet).c_str() );
|
throw Error( "BufferTree::splitNet(): Missing driver on %s.", getString(_rootNet).c_str() );
|
||||||
|
|
||||||
|
Net* origDriver = _rootNet;
|
||||||
|
|
||||||
Cluster::splitNet();
|
Cluster::splitNet();
|
||||||
if (_isDeepNet) {
|
if (_rootNet->isDeepNet()) {
|
||||||
Cell* topCell = getEtesian()->getCell();
|
Cell* topCell = getEtesian()->getCell();
|
||||||
Name topNetName = _rootNet->getName();
|
Name topNetName = _rootNet->getName();
|
||||||
Occurrence driverRpOcc = _rpDriver->getPlugOccurrence();
|
Occurrence driverRpOcc = _rpDriver->getPlugOccurrence();
|
||||||
|
origDriver = dynamic_cast<Net*>( static_cast<DeepNet*>( _rootNet )->getRootNetOccurrence().getEntity() );
|
||||||
_rootNet->destroy();
|
_rootNet->destroy();
|
||||||
_rootNet = Net::create( topCell, topNetName );
|
_rootNet = Net::create( topCell, topNetName );
|
||||||
Net* deepDriverNet = raddTransNet( _rootNet, driverRpOcc.getPath(), AS_DRIVER );
|
Net* deepDriverNet = raddTransNet( _rootNet, driverRpOcc.getPath(), AS_DRIVER );
|
||||||
|
@ -346,6 +351,7 @@ namespace Etesian {
|
||||||
RoutingPad::create( _rootNet, driverRpOcc, RoutingPad::BiggestArea );
|
RoutingPad::create( _rootNet, driverRpOcc, RoutingPad::BiggestArea );
|
||||||
}
|
}
|
||||||
createInput( _rootNet );
|
createInput( _rootNet );
|
||||||
|
rcleanupNet( origDriver );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,16 +367,15 @@ namespace Etesian {
|
||||||
RoutingPad* rpPin = NULL;
|
RoutingPad* rpPin = NULL;
|
||||||
for ( RoutingPad* rp : _rootNet->getRoutingPads() ) {
|
for ( RoutingPad* rp : _rootNet->getRoutingPads() ) {
|
||||||
Occurrence rpOccurrence = rp->getPlugOccurrence();
|
Occurrence rpOccurrence = rp->getPlugOccurrence();
|
||||||
if (rpOccurrence.getPath().isEmpty())
|
|
||||||
_isDeepNet = false;
|
|
||||||
Pin* pin = dynamic_cast<Pin* >( rpOccurrence.getEntity() );
|
Pin* pin = dynamic_cast<Pin* >( rpOccurrence.getEntity() );
|
||||||
if (pin) {
|
if (pin) {
|
||||||
if (not rpPin) {
|
if (not rpPin) {
|
||||||
if (dynamic_cast<Pin* >( rpOccurrence.getEntity() )) {
|
if (dynamic_cast<Pin* >( rpOccurrence.getEntity() )) {
|
||||||
|
cdebug_log(123,0) << "pin: " << rp << endl;
|
||||||
rpPin = rp;
|
rpPin = rp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cdebug_log(123,0) << "Excluded: " << pin << endl;
|
cdebug_log(123,0) << "Excluded second pin: " << pin << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Plug* rpPlug = dynamic_cast<Plug*>( rpOccurrence.getEntity() );
|
Plug* rpPlug = dynamic_cast<Plug*>( rpOccurrence.getEntity() );
|
||||||
|
@ -383,6 +388,7 @@ namespace Etesian {
|
||||||
cdebug_log(123,0) << "merge: " << _clustersStack[0].back()->getSize() << " " << rp << endl;
|
cdebug_log(123,0) << "merge: " << _clustersStack[0].back()->getSize() << " " << rp << endl;
|
||||||
_clustersStack[0].back()->merge( rp );
|
_clustersStack[0].back()->merge( rp );
|
||||||
} else {
|
} else {
|
||||||
|
cdebug_log(123,0) << "driver: " << rp << endl;
|
||||||
_rpDriver = rp;
|
_rpDriver = rp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -432,6 +438,8 @@ namespace Etesian {
|
||||||
|
|
||||||
uint32_t BufferTree::build ()
|
uint32_t BufferTree::build ()
|
||||||
{
|
{
|
||||||
|
DebugSession::open( _rootNet, 120, 130 );
|
||||||
|
cdebug_log(123,1) << "BufferTree::build() " << _rootNet << endl;
|
||||||
uint32_t bufferCount = 0;
|
uint32_t bufferCount = 0;
|
||||||
rpartition();
|
rpartition();
|
||||||
for ( vector<Cluster*>& clusters : _clustersStack ) {
|
for ( vector<Cluster*>& clusters : _clustersStack ) {
|
||||||
|
@ -440,9 +448,29 @@ namespace Etesian {
|
||||||
++bufferCount;
|
++bufferCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cdebug_tabw(123,-1);
|
||||||
|
DebugSession::close();
|
||||||
return bufferCount;
|
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
|
string BufferTree::_getTypeName () const
|
||||||
{ return "BufferTree"; }
|
{ return "BufferTree"; }
|
||||||
|
@ -484,6 +512,7 @@ namespace Etesian {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//DebugSession::open( 120, 130 );
|
||||||
UpdateSession::open();
|
UpdateSession::open();
|
||||||
Go::disableAutoMaterialization();
|
Go::disableAutoMaterialization();
|
||||||
_bufferCount = 0;
|
_bufferCount = 0;
|
||||||
|
@ -508,6 +537,7 @@ namespace Etesian {
|
||||||
// }
|
// }
|
||||||
Go::enableAutoMaterialization();
|
Go::enableAutoMaterialization();
|
||||||
UpdateSession::close();
|
UpdateSession::close();
|
||||||
|
//DebugSession::close();
|
||||||
|
|
||||||
stopMeasures();
|
stopMeasures();
|
||||||
printMeasures();
|
printMeasures();
|
||||||
|
|
|
@ -42,11 +42,11 @@ extern "C" {
|
||||||
// +=================================================================+
|
// +=================================================================+
|
||||||
|
|
||||||
|
|
||||||
static PyObject* PyLayoutGenerator_getVerboseLevel ( PyObject* )
|
static PyObject* PyLayoutGenerator_getVerboseLevel ( PyLayoutGenerator* )
|
||||||
{ return Py_BuildValue( "i", LayoutGenerator::getVerboseLevel() ); }
|
{ return Py_BuildValue( "i", LayoutGenerator::getVerboseLevel() ); }
|
||||||
|
|
||||||
|
|
||||||
static PyObject* PyLayoutGenerator_setVerboseLevel ( PyObject*, PyObject* args )
|
static PyObject* PyLayoutGenerator_setVerboseLevel ( PyLayoutGenerator*, PyObject* args )
|
||||||
{
|
{
|
||||||
int verboseLevel = 0;
|
int verboseLevel = 0;
|
||||||
if (PyArg_ParseTuple( args, "i:LayoutGenerator.setVerboseLevel", &verboseLevel )) {
|
if (PyArg_ParseTuple( args, "i:LayoutGenerator.setVerboseLevel", &verboseLevel )) {
|
||||||
|
@ -287,8 +287,8 @@ extern "C" {
|
||||||
|
|
||||||
|
|
||||||
PyMethodDef PyLayoutGenerator_Methods[] =
|
PyMethodDef PyLayoutGenerator_Methods[] =
|
||||||
{ { "getVerboseLevel" , (PyCFunction)PyLayoutGenerator_getVerboseLevel , METH_NOARGS|METH_STATIC, "Return the verbosity level." }
|
{ { "getVerboseLevel" , (PyCFunction)PyLayoutGenerator_getVerboseLevel , METH_NOARGS|METH_CLASS, "Return the verbosity level." }
|
||||||
, { "setVerboseLevel" , (PyCFunction)PyLayoutGenerator_setVerboseLevel , METH_STATIC, "Sets the verbosity level." }
|
, { "setVerboseLevel" , (PyCFunction)PyLayoutGenerator_setVerboseLevel , METH_CLASS, "Sets the verbosity level." }
|
||||||
, { "getDevice" , (PyCFunction)PyLayoutGenerator_getDevice , METH_NOARGS , "Return the Device currently loaded." }
|
, { "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." }
|
, { "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." }
|
, { "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)
|
void Contact::setLayer(const Layer* layer)
|
||||||
// ***************************************
|
// ***************************************
|
||||||
{
|
{
|
||||||
if (!layer)
|
if (not layer)
|
||||||
throw Error("Can't set layer : null layer");
|
throw Error( "Contact::setLayer(): Invalid NULL layer on %s.", getString(this).c_str() );
|
||||||
|
|
||||||
if (layer != _layer) {
|
if (layer != _layer) {
|
||||||
invalidate(false);
|
invalidate( false );
|
||||||
_layer = layer;
|
_layer = layer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Contact::setWidth(DbU::Unit width)
|
void Contact::setWidth(DbU::Unit width)
|
||||||
|
|
|
@ -777,6 +777,7 @@ string Net::_getString() const
|
||||||
{
|
{
|
||||||
string bs = Inherit::_getString();
|
string bs = Inherit::_getString();
|
||||||
string ds = "\"" + getString(_name) + "\" ";
|
string ds = "\"" + getString(_name) + "\" ";
|
||||||
|
ds += ((isDeepNet() ) ? "d" : "-");
|
||||||
ds += ((_isExternal ) ? "e" : "-");
|
ds += ((_isExternal ) ? "e" : "-");
|
||||||
ds += ((_isGlobal ) ? "g" : "-");
|
ds += ((_isGlobal ) ? "g" : "-");
|
||||||
ds += ((_isAutomatic) ? "a" : "-");
|
ds += ((_isAutomatic) ? "a" : "-");
|
||||||
|
|
|
@ -227,7 +227,8 @@ namespace Hurricane {
|
||||||
|
|
||||||
NetRoutingState* NetRoutingExtension::get ( const Net* net )
|
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;
|
_owner = net;
|
||||||
|
|
||||||
Property* property = _owner->getProperty( NetRoutingProperty::getPropertyName() );
|
Property* property = _owner->getProperty( NetRoutingProperty::getPropertyName() );
|
||||||
|
|
|
@ -62,8 +62,9 @@ extern "C" {
|
||||||
#if defined(__PYTHON_MODULE__)
|
#if defined(__PYTHON_MODULE__)
|
||||||
|
|
||||||
// Standard Accessors (Attributes).
|
// Standard Accessors (Attributes).
|
||||||
DirectGetLongAttribute(PyRectilinear_getX, getX, PyRectilinear, Rectilinear)
|
DirectGetLongAttribute(PyRectilinear_getX , getX , PyRectilinear, Rectilinear)
|
||||||
DirectGetLongAttribute(PyRectilinear_getY, getY, PyRectilinear, Rectilinear)
|
DirectGetLongAttribute(PyRectilinear_getY , getY , PyRectilinear, Rectilinear)
|
||||||
|
DirectGetBoolAttribute(PyRectilinear_isNonRectangle, isNonRectangle, PyRectilinear, Rectilinear)
|
||||||
|
|
||||||
// Standard Destroy (Attribute).
|
// Standard Destroy (Attribute).
|
||||||
DBoDestroyAttribute(PyRectilinear_destroy, PyRectilinear)
|
DBoDestroyAttribute(PyRectilinear_destroy, PyRectilinear)
|
||||||
|
@ -173,6 +174,7 @@ extern "C" {
|
||||||
PyMethodDef PyRectilinear_Methods[] =
|
PyMethodDef PyRectilinear_Methods[] =
|
||||||
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
|
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
|
||||||
, "Create a new Rectilinear polygon." }
|
, "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." }
|
, { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." }
|
||||||
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
|
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
|
||||||
, { "getBoundingBox", (PyCFunction)PyRectilinear_getBoundingBox, METH_NOARGS , "Return the Rectilinear Bounding Box." }
|
, { "getBoundingBox", (PyCFunction)PyRectilinear_getBoundingBox, METH_NOARGS , "Return the Rectilinear Bounding Box." }
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace Katana {
|
||||||
, _stateCount (1)
|
, _stateCount (1)
|
||||||
, _terminals (0)
|
, _terminals (0)
|
||||||
, _ripupCount (0)
|
, _ripupCount (0)
|
||||||
|
, _sameRipup (0)
|
||||||
, _leftMinExtend (DbU::Max)
|
, _leftMinExtend (DbU::Max)
|
||||||
, _rightMinExtend (DbU::Min)
|
, _rightMinExtend (DbU::Min)
|
||||||
, _attractors ()
|
, _attractors ()
|
||||||
|
|
|
@ -594,6 +594,7 @@ namespace Katana {
|
||||||
if (edge->getReservedCapacity() < hReservedMin)
|
if (edge->getReservedCapacity() < hReservedMin)
|
||||||
edge->reserveCapacity( hReservedMin - edge->getReservedCapacity() );
|
edge->reserveCapacity( hReservedMin - edge->getReservedCapacity() );
|
||||||
}
|
}
|
||||||
|
gcell->postGlobalAnnotate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -863,16 +864,6 @@ namespace Katana {
|
||||||
if (getState() > Anabatic::EngineDriving) return;
|
if (getState() > Anabatic::EngineDriving) return;
|
||||||
|
|
||||||
cdebug_tabw(155,1);
|
cdebug_tabw(155,1);
|
||||||
|
|
||||||
openSession();
|
|
||||||
for ( RoutingPlane* plane : _routingPlanes ) {
|
|
||||||
for ( Track* track : plane->getTracks() ) {
|
|
||||||
//track->expandMinArea();
|
|
||||||
track->repair();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Session::close();
|
|
||||||
|
|
||||||
setState( Anabatic::EngineDriving );
|
setState( Anabatic::EngineDriving );
|
||||||
_gutKatana();
|
_gutKatana();
|
||||||
|
|
||||||
|
|
|
@ -790,7 +790,12 @@ namespace Katana {
|
||||||
if (flags & Flags::PreRoutedStage) {
|
if (flags & Flags::PreRoutedStage) {
|
||||||
_katana->setFixedPreRouted();
|
_katana->setFixedPreRouted();
|
||||||
}
|
}
|
||||||
|
Session::revalidate();
|
||||||
|
|
||||||
|
for ( RoutingPlane* plane : _katana->getRoutingPlanes() ) {
|
||||||
|
for ( Track* track : plane->getTracks() )
|
||||||
|
track->repair();
|
||||||
|
}
|
||||||
Session::revalidate();
|
Session::revalidate();
|
||||||
Session::get()->isEmpty();
|
Session::get()->isEmpty();
|
||||||
|
|
||||||
|
|
|
@ -470,9 +470,9 @@ namespace Katana {
|
||||||
|
|
||||||
queue.repushInvalidateds();
|
queue.repushInvalidateds();
|
||||||
|
|
||||||
// if (getProcesseds() == 286892 + 1) {
|
// if (getProcesseds() == 48172 + 1) {
|
||||||
// UpdateSession::close();
|
// UpdateSession::close();
|
||||||
// Breakpoint::stop( 1, "Stopping before revalidating event 286892." );
|
// Breakpoint::stop( 0, "Stopping before revalidating event 3107." );
|
||||||
// UpdateSession::open();
|
// UpdateSession::open();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
|
@ -594,6 +594,11 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
|
|
||||||
_costs.push_back( new TrackCost(segment1,segment2,track1,track2,track1->getAxis(),symAxis) );
|
_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())
|
cdebug_log(155,0) << "AxisWeight:" << DbU::getValueString(_costs.back()->getRefCandidateAxis())
|
||||||
<< " sum:" << DbU::getValueString(_costs.back()->getAxisWeight())
|
<< " sum:" << DbU::getValueString(_costs.back()->getAxisWeight())
|
||||||
|
@ -1399,10 +1404,12 @@ namespace Katana {
|
||||||
and ( manipulator.getEvent()->getConstraints().isPonctual()
|
and ( manipulator.getEvent()->getConstraints().isPonctual()
|
||||||
or (isFullBlocked() and (_costs.size() > 7)))
|
or (isFullBlocked() and (_costs.size() > 7)))
|
||||||
and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) {
|
and segment->canMoveUp(1.0,Flags::CheckLowUpDensity|Flags::AllowTerminal) ) {
|
||||||
|
cdebug_log(159,0) << "Next state: MoveUp." << endl;
|
||||||
moveUpFlags |= Manipulator::AllowTerminalMoveUp;
|
moveUpFlags |= Manipulator::AllowTerminalMoveUp;
|
||||||
} else {
|
} else {
|
||||||
if ((success = manipulator.slacken(Flags::HalfSlacken))) {
|
if ((success = manipulator.slacken(Flags::HalfSlacken))) {
|
||||||
nextState = DataNegociate::RipupPerpandiculars;
|
nextState = DataNegociate::RipupPerpandiculars;
|
||||||
|
cdebug_log(159,0) << "Next state: RipupPerpandiculars (half-slacken succeeded)." << endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,19 +121,25 @@ namespace {
|
||||||
|
|
||||||
void GapSet::merge ( size_t i )
|
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()) {
|
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;
|
<< " " << _track->getSegment(i) << endl;
|
||||||
_spans.push_back( make_pair(i,i) );
|
_spans.push_back( make_pair(i,i) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ispan = 0;
|
size_t ispan = 0;
|
||||||
DbU::Unit segSourceU = element->getSourceU()+_halfSpacing;
|
cdebug_log(159,0) << "GapSet::merge() ["
|
||||||
DbU::Unit segTargetU = element->getTargetU()-_halfSpacing;
|
<< DbU::getValueString(segSourceU) << " "
|
||||||
cdebug_log(159,0) << "GapSet::merge() " << element << endl;
|
<< DbU::getValueString(segTargetU) << "] "
|
||||||
|
<< element << endl;
|
||||||
for ( ; ispan<_spans.size() ; ++ispan ) {
|
for ( ; ispan<_spans.size() ; ++ispan ) {
|
||||||
if (targetU(ispan) >= segSourceU) {
|
if (targetU(ispan) >= segSourceU) {
|
||||||
if (targetU(ispan) >= segTargetU) {
|
if (targetU(ispan) >= segTargetU) {
|
||||||
|
@ -389,14 +395,14 @@ namespace Katana {
|
||||||
|
|
||||||
TrackElement* Track::getPrevious ( size_t& index, Net* net ) const
|
TrackElement* Track::getPrevious ( size_t& index, Net* net ) const
|
||||||
{
|
{
|
||||||
for ( index-- ; index != npos ; index-- ) {
|
cdebug_log(155,0) << "Track::getPrevious() " << index << " for " << net << endl;
|
||||||
cdebug_log(140,0) << index << ":" << _segments[index] << endl;
|
if ((index == npos) or (index == 0)) return NULL;
|
||||||
|
do {
|
||||||
if (_segments[index]->getNet() == net) continue;
|
--index;
|
||||||
return _segments[index];
|
cdebug_log(155,0) << "| " << index << ":" << _segments[index] << endl;
|
||||||
}
|
if (_segments[index]->getNet() != net) return _segments[index];
|
||||||
|
} while ( index != 0 );
|
||||||
index = npos;
|
index = npos;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,8 +428,8 @@ namespace Katana {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position < _min) {
|
if (position < _min - getLayerGauge()->getPitch()*2) {
|
||||||
cerr << Warning( " Position %s inferior to the lower bound of %s. Returning npos."
|
cerr << Warning( " Position %s too far outside the lower bound of %s. Returning npos."
|
||||||
, DbU::getValueString(position).c_str()
|
, DbU::getValueString(position).c_str()
|
||||||
, getString(this).c_str() ) << endl;
|
, getString(this).c_str() ) << endl;
|
||||||
state = BeforeFirstElement;
|
state = BeforeFirstElement;
|
||||||
|
@ -431,8 +437,8 @@ namespace Katana {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position > _max) {
|
if (position > _max + getLayerGauge()->getPitch()*2) {
|
||||||
cerr << Warning( " Position %s superior to the upper bound of %s. Returning npos."
|
cerr << Warning( " Position %s is too far outside the upper bound of %s. Returning npos."
|
||||||
, DbU::getValueString(position).c_str()
|
, DbU::getValueString(position).c_str()
|
||||||
, getString(this).c_str() ) << endl;
|
, getString(this).c_str() ) << endl;
|
||||||
state = AfterLastElement;
|
state = AfterLastElement;
|
||||||
|
@ -682,7 +688,7 @@ namespace Katana {
|
||||||
DbU::Unit minFree = _min;
|
DbU::Unit minFree = _min;
|
||||||
cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " (track min)" << endl;
|
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)
|
if (_segments[begin]->getNet() == net)
|
||||||
getPrevious( begin, net );
|
getPrevious( begin, net );
|
||||||
|
|
||||||
|
@ -1005,11 +1011,12 @@ namespace Katana {
|
||||||
|
|
||||||
uint32_t Track::repair () const
|
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;
|
cdebug_log(159,0) << "Track::repair() " << this << endl;
|
||||||
|
|
||||||
if (_segments.empty()) {
|
if (_segments.empty()) {
|
||||||
fillHole( getMin(), getMax() );
|
fillHole( getMin(), getMax() );
|
||||||
|
//if ((getIndex() == 3473) and isHorizontal()) DebugSession::close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DbU::Unit minSpacing = getLayer()->getMinimalSpacing();
|
DbU::Unit minSpacing = getLayer()->getMinimalSpacing();
|
||||||
|
@ -1024,6 +1031,7 @@ namespace Katana {
|
||||||
GapSet gapsetCurr ( this );
|
GapSet gapsetCurr ( this );
|
||||||
for ( size_t i=0 ; i<_segments.size()-1 ; i++ ) {
|
for ( size_t i=0 ; i<_segments.size()-1 ; i++ ) {
|
||||||
cdebug_log(159,0) << "[" << i << "] " << _segments[i] << endl;
|
cdebug_log(159,0) << "[" << i << "] " << _segments[i] << endl;
|
||||||
|
if (_segments[i]->isNonPref()) continue;
|
||||||
netChange = false;
|
netChange = false;
|
||||||
gapsetCurr.merge( i );
|
gapsetCurr.merge( i );
|
||||||
if ( (_segments[i]->getNet() != _segments[i+1]->getNet())
|
if ( (_segments[i]->getNet() != _segments[i+1]->getNet())
|
||||||
|
@ -1033,19 +1041,25 @@ namespace Katana {
|
||||||
spacing = gapsetCurr.spansSourceU() - gapsetPrev.spansTargetU();
|
spacing = gapsetCurr.spansSourceU() - gapsetPrev.spansTargetU();
|
||||||
if (spacing < minSpacing) {
|
if (spacing < minSpacing) {
|
||||||
spacing = minSpacing - spacing;
|
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)) {
|
if (prev and (prev->getDuTarget() >= spacing)) {
|
||||||
prev->setDuSource( prev->getDuSource() - spacing );
|
prev->setDuSource( prev->getDuSource() - spacing );
|
||||||
prev->setDuTarget( prev->getDuTarget() - 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(this).c_str()
|
||||||
, getString(prev).c_str() ) << endl;
|
, getString(prev).c_str() ) << endl;
|
||||||
} else {
|
} 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)) {
|
if (curr and (-curr->getDuSource() >= spacing)) {
|
||||||
curr->setDuSource( curr->getDuSource() + spacing );
|
curr->setDuSource( curr->getDuSource() + spacing );
|
||||||
curr->setDuTarget( curr->getDuTarget() + 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(this).c_str()
|
||||||
, getString(curr).c_str() ) << endl;
|
, getString(curr).c_str() ) << endl;
|
||||||
}
|
}
|
||||||
|
@ -1074,14 +1088,15 @@ namespace Katana {
|
||||||
<< j+1 << "=[" << DbU::getValueString(gapsetCurr.sourceU(j+1))
|
<< j+1 << "=[" << DbU::getValueString(gapsetCurr.sourceU(j+1))
|
||||||
<< " " << DbU::getValueString(gapsetCurr.targetU(j+1)) << "]" << endl;
|
<< " " << DbU::getValueString(gapsetCurr.targetU(j+1)) << "]" << endl;
|
||||||
if (gapsetCurr.span(j+1).first >= _segments.size()) {
|
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 {
|
} 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;
|
cdebug_log(159,0) << "spacing:" << DbU::getValueString(spacing) << " " << first << endl;
|
||||||
if (first == NULL) {
|
if (first == NULL) {
|
||||||
cerr << Error("null first, NOT correcting gap") << endl;
|
cerr << Bug("Track::repair(): Base of first element is NULL, *unable* to correct gap.") << endl;
|
||||||
} else {
|
} else if (not first->isNonPref()) {
|
||||||
for ( AutoSegment* segment : first->getAligneds() ) {
|
for ( AutoSegment* segment : first->getAligneds() ) {
|
||||||
if (segment->getSourcePosition() < first->getSourcePosition())
|
if (segment->getSourcePosition() < first->getSourcePosition())
|
||||||
first = segment;
|
first = segment;
|
||||||
|
@ -1091,9 +1106,10 @@ namespace Katana {
|
||||||
cdebug_log(159,0) << "duSource:" << DbU::getValueString(first->getDuSource()) << endl;
|
cdebug_log(159,0) << "duSource:" << DbU::getValueString(first->getDuSource()) << endl;
|
||||||
//first->setDuSource( first->getDuSource() - spacing - minSpacing/2 );
|
//first->setDuSource( first->getDuSource() - spacing - minSpacing/2 );
|
||||||
first->setDuSource( first->getDuSource() - spacing );
|
first->setDuSource( first->getDuSource() - spacing );
|
||||||
|
element->invalidate();
|
||||||
}
|
}
|
||||||
++gaps;
|
++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(this).c_str()
|
||||||
, getString(_segments[(i) ? i-1 : 0]).c_str() ) << endl;
|
, getString(_segments[(i) ? i-1 : 0]).c_str() ) << endl;
|
||||||
cdebug_log(159,0) << first << endl;
|
cdebug_log(159,0) << first << endl;
|
||||||
|
@ -1124,7 +1140,7 @@ namespace Katana {
|
||||||
if (spacing > 10*getLayerGauge()->getPitch())
|
if (spacing > 10*getLayerGauge()->getPitch())
|
||||||
fillHole( lastTargetU, getMax() );
|
fillHole( lastTargetU, getMax() );
|
||||||
|
|
||||||
//if ((getIndex() == 1011) and isHorizontal()) DebugSession::close();
|
//if ((getIndex() == 3473) and isHorizontal()) DebugSession::close();
|
||||||
return gaps;
|
return gaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1215,7 +1231,9 @@ namespace Katana {
|
||||||
++j;
|
++j;
|
||||||
continue;
|
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) {
|
if (_segments[j]->base()->getSpanLength() < techMinLength) {
|
||||||
cerr << Error( "Below minimal length/area for %s:\n length:%s, minimal length:%s"
|
cerr << Error( "Below minimal length/area for %s:\n length:%s, minimal length:%s"
|
||||||
, getString(_segments[j]).c_str()
|
, getString(_segments[j]).c_str()
|
||||||
|
|
|
@ -110,17 +110,18 @@ namespace Katana {
|
||||||
|
|
||||||
bool TrackCost::Compare::operator() ( const TrackCost* lhs, const TrackCost* rhs )
|
bool TrackCost::Compare::operator() ( const TrackCost* lhs, const TrackCost* rhs )
|
||||||
{
|
{
|
||||||
if ( lhs->isInfinite () xor rhs->isInfinite () ) return rhs->isInfinite();
|
if (lhs->isInfinite () xor rhs->isInfinite ()) return rhs->isInfinite();
|
||||||
if ( lhs->isAtRipupLimit() xor rhs->isAtRipupLimit() ) return rhs->isAtRipupLimit();
|
if (lhs->isAtRipupLimit() xor rhs->isAtRipupLimit()) return rhs->isAtRipupLimit();
|
||||||
|
if (lhs->isBlacklisted() xor rhs->isBlacklisted ()) return rhs->isBlacklisted();
|
||||||
|
|
||||||
if ( (_flags & TrackCost::DiscardGlobals)
|
if ( (_flags & TrackCost::DiscardGlobals)
|
||||||
and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) )
|
and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) )
|
||||||
return 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 true;
|
||||||
if ( lhs->_ripupCount > (int)Session::getRipupCost() + rhs->_ripupCount ) return false;
|
if (lhs->_ripupCount > (int)Session::getRipupCost() + rhs->_ripupCount) return false;
|
||||||
|
|
||||||
//int lhsRipupCost = (lhs->_dataState<<2) + lhs->_ripupCount;
|
//int lhsRipupCost = (lhs->_dataState<<2) + lhs->_ripupCount;
|
||||||
//int rhsRipupCost = (rhs->_dataState<<2) + rhs->_ripupCount;
|
//int rhsRipupCost = (rhs->_dataState<<2) + rhs->_ripupCount;
|
||||||
|
@ -132,7 +133,7 @@ namespace Katana {
|
||||||
// if ( lhs->_longuestOverlap > rhs->_longuestOverlap ) return false;
|
// 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 (not (_flags & TrackCost::IgnoreTerminals)) {
|
||||||
if ( lhs->_terminals < rhs->_terminals ) return true;
|
if ( lhs->_terminals < rhs->_terminals ) return true;
|
||||||
|
@ -166,15 +167,15 @@ namespace Katana {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( not (_flags & TrackCost::IgnoreAxisWeight) ) {
|
if ( not (_flags & TrackCost::IgnoreAxisWeight) ) {
|
||||||
if ( lhs->_axisWeight < rhs->_axisWeight ) return true;
|
if (lhs->_axisWeight < rhs->_axisWeight) return true;
|
||||||
if ( lhs->_axisWeight > rhs->_axisWeight ) return false;
|
if (lhs->_axisWeight > rhs->_axisWeight) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( lhs->_deltaPerpand < rhs->_deltaPerpand ) return true;
|
if (lhs->_deltaPerpand < rhs->_deltaPerpand) return true;
|
||||||
if ( lhs->_deltaPerpand > rhs->_deltaPerpand ) return false;
|
if (lhs->_deltaPerpand > rhs->_deltaPerpand) return false;
|
||||||
|
|
||||||
if ( lhs->_distanceToFixed > rhs->_distanceToFixed ) return true;
|
if (lhs->_distanceToFixed > rhs->_distanceToFixed) return true;
|
||||||
if ( lhs->_distanceToFixed < rhs->_distanceToFixed ) return false;
|
if (lhs->_distanceToFixed < rhs->_distanceToFixed) return false;
|
||||||
|
|
||||||
return lhs->getTrack(0)->getAxis() < rhs->getTrack(0)->getAxis();
|
return lhs->getTrack(0)->getAxis() < rhs->getTrack(0)->getAxis();
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,6 +478,8 @@ namespace Katana {
|
||||||
|
|
||||||
void TrackSegment::revalidate ()
|
void TrackSegment::revalidate ()
|
||||||
{
|
{
|
||||||
|
DebugSession::open( getNet(), 159, 160 );
|
||||||
|
|
||||||
unsetFlags( TElemCreated );
|
unsetFlags( TElemCreated );
|
||||||
cdebug_log(159,0) << "revalidate() - " << this << endl;
|
cdebug_log(159,0) << "revalidate() - " << this << endl;
|
||||||
|
|
||||||
|
@ -501,11 +503,17 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsetFlags( TElemInvalidated );
|
unsetFlags( TElemInvalidated );
|
||||||
|
|
||||||
|
DebugSession::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TrackSegment::setAxis ( DbU::Unit axis, uint32_t flags )
|
void TrackSegment::setAxis ( DbU::Unit axis, uint32_t flags )
|
||||||
{
|
{
|
||||||
|
if (_data) {
|
||||||
|
if (axis == getAxis()) _data->incSameRipup();
|
||||||
|
else _data->resetSameRipup();
|
||||||
|
}
|
||||||
_base->setAxis( axis, flags );
|
_base->setAxis( axis, flags );
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace Katana {
|
||||||
inline uint32_t getState () const;
|
inline uint32_t getState () const;
|
||||||
inline uint32_t getStateCount () const;
|
inline uint32_t getStateCount () const;
|
||||||
inline uint32_t getRipupCount () const;
|
inline uint32_t getRipupCount () const;
|
||||||
|
inline uint32_t getSameRipup () const;
|
||||||
inline uint32_t getStateAndRipupCount () const;
|
inline uint32_t getStateAndRipupCount () const;
|
||||||
DbU::Unit getWiringDelta ( DbU::Unit axis ) const;
|
DbU::Unit getWiringDelta ( DbU::Unit axis ) const;
|
||||||
inline const vector<TrackElement*>& getPerpandiculars () const;
|
inline const vector<TrackElement*>& getPerpandiculars () const;
|
||||||
|
@ -87,6 +88,8 @@ namespace Katana {
|
||||||
inline void decRipupCount ();
|
inline void decRipupCount ();
|
||||||
inline void resetRipupCount ();
|
inline void resetRipupCount ();
|
||||||
inline void resetStateCount ();
|
inline void resetStateCount ();
|
||||||
|
inline void resetSameRipup ();
|
||||||
|
inline void incSameRipup ();
|
||||||
void update ();
|
void update ();
|
||||||
static string getStateString ( uint32_t state, unsigned int stateCount );
|
static string getStateString ( uint32_t state, unsigned int stateCount );
|
||||||
static string getStateString ( DataNegociate* );
|
static string getStateString ( DataNegociate* );
|
||||||
|
@ -103,6 +106,7 @@ namespace Katana {
|
||||||
unsigned int _stateCount : 5;
|
unsigned int _stateCount : 5;
|
||||||
unsigned int _terminals : 5;
|
unsigned int _terminals : 5;
|
||||||
unsigned int _ripupCount : 16;
|
unsigned int _ripupCount : 16;
|
||||||
|
unsigned int _sameRipup : 8;
|
||||||
DbU::Unit _leftMinExtend;
|
DbU::Unit _leftMinExtend;
|
||||||
DbU::Unit _rightMinExtend;
|
DbU::Unit _rightMinExtend;
|
||||||
vector<DbU::Unit> _attractors;
|
vector<DbU::Unit> _attractors;
|
||||||
|
@ -124,6 +128,7 @@ namespace Katana {
|
||||||
inline uint32_t DataNegociate::getState () const { return _state; }
|
inline uint32_t DataNegociate::getState () const { return _state; }
|
||||||
inline uint32_t DataNegociate::getTerminals () const { return _terminals; }
|
inline uint32_t DataNegociate::getTerminals () const { return _terminals; }
|
||||||
inline uint32_t DataNegociate::getRipupCount () const { return _ripupCount; }
|
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::getLeftMinExtend () const { return _leftMinExtend; }
|
||||||
inline DbU::Unit DataNegociate::getRightMinExtend () const { return _rightMinExtend; }
|
inline DbU::Unit DataNegociate::getRightMinExtend () const { return _rightMinExtend; }
|
||||||
inline Net* DataNegociate::getNet () const { return _net; }
|
inline Net* DataNegociate::getNet () const { return _net; }
|
||||||
|
@ -137,6 +142,8 @@ namespace Katana {
|
||||||
inline void DataNegociate::incRipupCount () { _ripupCount++; }
|
inline void DataNegociate::incRipupCount () { _ripupCount++; }
|
||||||
inline void DataNegociate::decRipupCount () { if (_ripupCount) _ripupCount--; }
|
inline void DataNegociate::decRipupCount () { if (_ripupCount) _ripupCount--; }
|
||||||
inline void DataNegociate::resetRipupCount () { _ripupCount = 0; }
|
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 string DataNegociate::_getTypeName () const { return "DataNegociate"; }
|
||||||
|
|
||||||
inline void DataNegociate::setState ( uint32_t state, Flags flags )
|
inline void DataNegociate::setState ( uint32_t state, Flags flags )
|
||||||
|
|
|
@ -100,6 +100,8 @@ namespace Katana {
|
||||||
getPostEventCb ();
|
getPostEventCb ();
|
||||||
inline NegociateWindow* getNegociateWindow ();
|
inline NegociateWindow* getNegociateWindow ();
|
||||||
inline size_t getRoutingPlanesSize () const;
|
inline size_t getRoutingPlanesSize () const;
|
||||||
|
inline const std::vector<RoutingPlane*>&
|
||||||
|
getRoutingPlanes () const;
|
||||||
RoutingPlane* getRoutingPlaneByIndex ( size_t index ) const;
|
RoutingPlane* getRoutingPlaneByIndex ( size_t index ) const;
|
||||||
RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const;
|
RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const;
|
||||||
Track* getTrackByPosition ( const Layer*, DbU::Unit axis, uint32_t mode=Constant::Nearest ) 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 Block* KatanaEngine::getBlock ( size_t i ) const { return (i < _blocks.size()) ? _blocks[i] : NULL; }
|
||||||
inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; }
|
inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; }
|
||||||
inline size_t KatanaEngine::getRoutingPlanesSize () const { return _routingPlanes.size(); }
|
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::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
|
||||||
inline void KatanaEngine::setStage ( uint32_t stage ) { _stage=stage; }
|
inline void KatanaEngine::setStage ( uint32_t stage ) { _stage=stage; }
|
||||||
inline void KatanaEngine::setEventLimit ( uint64_t limit ) { _configuration->setEventsLimit(limit); }
|
inline void KatanaEngine::setEventLimit ( uint64_t limit ) { _configuration->setEventsLimit(limit); }
|
||||||
|
|
|
@ -61,6 +61,7 @@ namespace Katana {
|
||||||
, AtRipupLimit = (1 << 18)
|
, AtRipupLimit = (1 << 18)
|
||||||
, IgnoreTerminals = (1 << 19)
|
, IgnoreTerminals = (1 << 19)
|
||||||
, IgnoreShort = (1 << 20)
|
, IgnoreShort = (1 << 20)
|
||||||
|
, Blacklisted = (1 << 21)
|
||||||
, MergeMask = ForGlobal |Blockage|Fixed |Infinite
|
, MergeMask = ForGlobal |Blockage|Fixed |Infinite
|
||||||
|HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal
|
|HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal
|
||||||
|GlobalEnclosed |AtRipupLimit
|
|GlobalEnclosed |AtRipupLimit
|
||||||
|
@ -102,6 +103,7 @@ namespace Katana {
|
||||||
inline bool isOverlapGlobal () const;
|
inline bool isOverlapGlobal () const;
|
||||||
inline bool isGlobalEnclosed () const;
|
inline bool isGlobalEnclosed () const;
|
||||||
inline bool isAtRipupLimit () const;
|
inline bool isAtRipupLimit () const;
|
||||||
|
inline bool isBlacklisted () const;
|
||||||
bool isFree () const;
|
bool isFree () const;
|
||||||
inline bool isSymmetric () const;
|
inline bool isSymmetric () const;
|
||||||
inline bool isWide () const;
|
inline bool isWide () const;
|
||||||
|
@ -148,6 +150,7 @@ namespace Katana {
|
||||||
inline void setOverlapGlobal ();
|
inline void setOverlapGlobal ();
|
||||||
inline void setGlobalEnclosed ();
|
inline void setGlobalEnclosed ();
|
||||||
inline void setAtRipupLimit ();
|
inline void setAtRipupLimit ();
|
||||||
|
inline void setBlacklisted ();
|
||||||
inline void incTerminals ( uint32_t );
|
inline void incTerminals ( uint32_t );
|
||||||
inline void incDelta ( DbU::Unit );
|
inline void incDelta ( DbU::Unit );
|
||||||
inline void incDeltaPerpand ( DbU::Unit );
|
inline void incDeltaPerpand ( DbU::Unit );
|
||||||
|
@ -208,6 +211,7 @@ namespace Katana {
|
||||||
inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; }
|
inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; }
|
||||||
inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; }
|
inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; }
|
||||||
inline bool TrackCost::isAtRipupLimit () const { return _flags & AtRipupLimit; }
|
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::isSymmetric () const { return _flags & Symmetric; }
|
||||||
inline bool TrackCost::isWide () const { return (_span > 1); }
|
inline bool TrackCost::isWide () const { return (_span > 1); }
|
||||||
inline bool TrackCost::doIgnoreShort () const { return _flags & IgnoreShort; }
|
inline bool TrackCost::doIgnoreShort () const { return _flags & IgnoreShort; }
|
||||||
|
@ -245,6 +249,7 @@ namespace Katana {
|
||||||
inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; }
|
inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; }
|
||||||
inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; }
|
inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; }
|
||||||
inline void TrackCost::setAtRipupLimit () { _flags |= AtRipupLimit; }
|
inline void TrackCost::setAtRipupLimit () { _flags |= AtRipupLimit; }
|
||||||
|
inline void TrackCost::setBlacklisted () { _flags |= Blacklisted; }
|
||||||
inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; }
|
inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; }
|
||||||
inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; }
|
inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; }
|
||||||
inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; }
|
inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; }
|
||||||
|
|
Loading…
Reference in New Issue