TrackCost clean support for symmetric and wide segments.

* New: In Katana::TrackCost, the TrackElement and it's optional
    symmetric are now kept as attribute of a TrackCost. The cost
    is completly computed inside the constructor.
      TrackCost now support any mix of symmetric event and wide
    segments.
      The cost is now computed by adding directly to the current
    one instead of creating secondaries that are merged afterwards.
    As a consequence, remove all copy construction and merge
    capabilities.
      All the various methods used to compute the cost are renamed
    "addOverlapcost()" in all the various related objects.
      As a reminder, the overal cost method call is as follow:
        1. TrackCost constructor on a TrackElement.
           2. Call TrackElement::addOverlapcost()
              3. For all Track under the TrackElement, call
                 Track::addOverlapCost()
                 4. For all other TrackElement intersecting with
                    the overlap interval call:
                    TrackElement::incOverlapCost()
                    5. The callback overlap function for segments
                       is called (defined in NegociateWidow).
      Don't confuse:
      - TrackElement::addOverlapCost(), which compute the cost of
          inserting the segment inside a track (or a set of).
      - TrackElement::incOverlapCost(), which compute the cost of
          overlaping with this already inserted segment. It is the
          other way around of the previous one.
* Change: In Katana::SegmentFsm, use a vector of pointer to TrackCost
    instead of an object to avoid copy construction.
This commit is contained in:
Jean-Paul Chaput 2017-06-10 12:27:25 +02:00
parent 8a73b03fd8
commit 8d4fdf3471
25 changed files with 899 additions and 489 deletions

View File

@ -432,8 +432,8 @@ namespace Anabatic {
void AutoHorizontal::updatePositions () void AutoHorizontal::updatePositions ()
{ {
_sourcePosition = _horizontal->getSourceX() - Session::getExtensionCap(getLayer()); _sourcePosition = _horizontal->getSourceX() - getExtensionCap();
_targetPosition = _horizontal->getTargetX() + Session::getExtensionCap(getLayer()); _targetPosition = _horizontal->getTargetX() + getExtensionCap();
} }
@ -453,8 +453,8 @@ namespace Anabatic {
bool AutoHorizontal::checkPositions () const bool AutoHorizontal::checkPositions () const
{ {
bool coherency = true; bool coherency = true;
DbU::Unit sourcePosition = _horizontal->getSourceX() - Session::getExtensionCap(getLayer()); DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap();
DbU::Unit targetPosition = _horizontal->getTargetX() + Session::getExtensionCap(getLayer()); DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap();
if ( _sourcePosition != sourcePosition ) { if ( _sourcePosition != sourcePosition ) {
cerr << Error ( "%s\n Source position incoherency: " cerr << Error ( "%s\n Source position incoherency: "

View File

@ -608,6 +608,13 @@ namespace Anabatic {
} }
DbU::Unit AutoSegment::getExtensionCap () const
{
DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) );
if (getWidth() <= mWidth) return Session::getExtensionCap( getLayer() );
return getWidth() / 2;
}
DbU::Unit AutoSegment::getSlack () const DbU::Unit AutoSegment::getSlack () const
{ {
DbU::Unit constraintMin; DbU::Unit constraintMin;

View File

@ -371,8 +371,8 @@ namespace Anabatic {
void AutoVertical::updatePositions () void AutoVertical::updatePositions ()
{ {
_sourcePosition = _vertical->getSourceY() - Session::getExtensionCap(getLayer()); _sourcePosition = _vertical->getSourceY() - getExtensionCap();
_targetPosition = _vertical->getTargetY() + Session::getExtensionCap(getLayer()); _targetPosition = _vertical->getTargetY() + getExtensionCap();
} }
@ -392,8 +392,8 @@ namespace Anabatic {
bool AutoVertical::checkPositions () const bool AutoVertical::checkPositions () const
{ {
bool coherency = true; bool coherency = true;
DbU::Unit sourcePosition = _vertical->getSourceY() - Session::getExtensionCap(getLayer()); DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap();
DbU::Unit targetPosition = _vertical->getTargetY() + Session::getExtensionCap(getLayer()); DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap();
if ( _sourcePosition != sourcePosition ) { if ( _sourcePosition != sourcePosition ) {
cerr << Error ( "%s\n Source position incoherency: " cerr << Error ( "%s\n Source position incoherency: "

View File

@ -231,6 +231,7 @@ namespace Anabatic {
inline unsigned int getDepth () const; inline unsigned int getDepth () const;
inline DbU::Unit getPitch () const; inline DbU::Unit getPitch () const;
DbU::Unit getPPitch () const; DbU::Unit getPPitch () const;
DbU::Unit getExtensionCap () const;
inline DbU::Unit getAxis () const; inline DbU::Unit getAxis () const;
virtual DbU::Unit getSourceU () const = 0; virtual DbU::Unit getSourceU () const = 0;
virtual DbU::Unit getTargetU () const = 0; virtual DbU::Unit getTargetU () const = 0;

View File

@ -41,8 +41,8 @@ def kwParseMain ( **kw ):
editor = kw['editor'] editor = kw['editor']
if cell == None: cell = editor.getCell() if cell == None: cell = editor.getCell()
if cell == None: #if cell == None:
raise ErrorMessage( 3, 'Chip: No cell loaded yet.' ) # raise ErrorMessage( 3, 'Chip: No cell loaded yet.' )
return cell, editor return cell, editor

View File

@ -96,6 +96,9 @@ namespace Hurricane {
void DebugSession::open ( int minLevel, int maxLevel ) void DebugSession::open ( int minLevel, int maxLevel )
{ {
if (cdebug.getMinLevel() < minLevel) minLevel = cdebug.getMinLevel();
if (cdebug.getMaxLevel() > maxLevel) maxLevel = cdebug.getMaxLevel();
_singleton->_levels.push( make_pair( cdebug.setMinLevel(minLevel) _singleton->_levels.push( make_pair( cdebug.setMinLevel(minLevel)
, cdebug.setMaxLevel(maxLevel) ) ); , cdebug.setMaxLevel(maxLevel) ) );
} }
@ -103,6 +106,9 @@ namespace Hurricane {
void DebugSession::open ( const void* symbol, int minLevel, int maxLevel ) void DebugSession::open ( const void* symbol, int minLevel, int maxLevel )
{ {
if (cdebug.getMinLevel() < minLevel) minLevel = cdebug.getMinLevel();
if (cdebug.getMaxLevel() > maxLevel) maxLevel = cdebug.getMaxLevel();
if ( _singleton->_isTraced(symbol) ) if ( _singleton->_isTraced(symbol) )
_singleton->_levels.push( make_pair( cdebug.setMinLevel(minLevel) _singleton->_levels.push( make_pair( cdebug.setMinLevel(minLevel)
, cdebug.setMaxLevel(maxLevel) ) ); , cdebug.setMaxLevel(maxLevel) ) );

View File

@ -15,6 +15,8 @@
katana/DataSymmetric.h katana/DataSymmetric.h
katana/TrackElement.h katana/TrackElements.h katana/TrackElement.h katana/TrackElements.h
katana/TrackSegment.h katana/TrackSegment.h
katana/TrackSegmentRegular.h
katana/TrackSegmentWide.h
katana/TrackFixedSegment.h katana/TrackFixedSegment.h
katana/TrackMarker.h katana/TrackMarker.h
katana/Track.h katana/Track.h
@ -47,6 +49,8 @@
TrackElement.cpp TrackElement.cpp
TrackElements.cpp TrackElements.cpp
TrackSegment.cpp TrackSegment.cpp
TrackSegmentRegular.cpp
TrackSegmentWide.cpp
TrackFixedSegment.cpp TrackFixedSegment.cpp
TrackMarker.cpp TrackMarker.cpp
Track.cpp Track.cpp

View File

@ -781,7 +781,7 @@ namespace Katana {
_fsm.setState ( SegmentFsm::OtherRipup ); _fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment _fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4
, _fsm.getCost(itrack).getTrack()->getAxis() ); , _fsm.getTrack1(itrack)->getAxis() );
uint32_t flags = 0; uint32_t flags = 0;
if ( rightIntrication ) flags |= RightAxisHint; if ( rightIntrication ) flags |= RightAxisHint;
@ -850,7 +850,7 @@ namespace Katana {
_fsm.setState ( SegmentFsm::OtherRipup ); _fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment _fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis , SegmentAction::SelfInsert|SegmentAction::MoveToAxis
, _fsm.getCost(itrack).getTrack()->getAxis() ); , _fsm.getTrack(itrack)->getAxis() );
} }
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
@ -932,15 +932,15 @@ namespace Katana {
{ {
cdebug_log(159,1) << "Manipulator::forceOverLocals()" << endl; cdebug_log(159,1) << "Manipulator::forceOverLocals()" << endl;
vector< array<TrackCost,2> >& costs = _fsm.getCosts(); vector<TrackCost*>& costs = _fsm.getCosts();
size_t itrack = 0; size_t itrack = 0;
for ( ; itrack<costs.size() ; ++itrack ) { for ( ; itrack<costs.size() ; ++itrack ) {
cdebug_log(159,0) << "Trying itrack:" << itrack << endl; cdebug_log(159,0) << "Trying itrack:" << itrack << endl;
if ( costs[itrack][0].isFixed() if ( costs[itrack]->isFixed()
or costs[itrack][0].isBlockage() or costs[itrack]->isBlockage()
or costs[itrack][0].isInfinite() or costs[itrack]->isInfinite()
or costs[itrack][0].isOverlapGlobal() ) or costs[itrack]->isOverlapGlobal() )
continue; continue;
bool success = true; bool success = true;
@ -979,7 +979,7 @@ namespace Katana {
_fsm.setState ( SegmentFsm::OtherRipup ); _fsm.setState ( SegmentFsm::OtherRipup );
_fsm.addAction( _segment _fsm.addAction( _segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis , SegmentAction::SelfInsert|SegmentAction::MoveToAxis
, _fsm.getCost(itrack).getTrack()->getAxis() , _fsm.getTrack(itrack)->getAxis()
); );
break; break;
} }

View File

@ -507,7 +507,7 @@ namespace Katana {
cmess2 << " <event:" << tty::bold << right << setw(8) << setfill('0') cmess2 << " <event:" << tty::bold << right << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << tty::reset << RoutingEvent::getProcesseds() << tty::reset
<< " remains:" << right << setw(8) << setfill('0') << " remains:" << right << setw(8) << setfill('0')
<< _eventQueue.size()+1 << _eventQueue.size()
<< setfill(' ') << tty::reset << ">" << tty::cr; << setfill(' ') << tty::reset << ">" << tty::cr;
cmess2.flush (); cmess2.flush ();
} else { } else {

View File

@ -475,7 +475,7 @@ namespace Katana {
itrack = 0; itrack = 0;
if ( (not isOverConstrained()) and fsm.canRipup() ) { if ( (not isOverConstrained()) and fsm.canRipup() ) {
if (fsm.getCosts().size() and fsm.getCost(itrack).isFree()) { if (fsm.getCosts().size() and fsm.getCost(itrack)->isFree()) {
cdebug_log(159,0) << "Insert in free space " << this << endl; cdebug_log(159,0) << "Insert in free space " << this << endl;
fsm.bindToTrack( itrack ); fsm.bindToTrack( itrack );
} else { } else {
@ -491,7 +491,7 @@ namespace Katana {
} }
for ( itrack=0 ; itrack<fsm.getCosts().size() ; itrack++ ) { for ( itrack=0 ; itrack<fsm.getCosts().size() ; itrack++ ) {
cdebug_log(159,0) << "Trying Track: " << itrack << endl; cdebug_log(159,0) << "Trying Track: " << itrack << endl;
if (fsm.getCost(itrack).isInfinite()) break; if (fsm.getCost(itrack)->isInfinite()) break;
if (fsm.insertInTrack(itrack)) break; if (fsm.insertInTrack(itrack)) break;
resetInsertState(); resetInsertState();
} // Next ripup is possible. } // Next ripup is possible.
@ -516,7 +516,7 @@ namespace Katana {
fsm.doActions(); fsm.doActions();
if (itrack < fsm.getCosts().size()) { if (itrack < fsm.getCosts().size()) {
cdebug_log(159,0) << "Placed: @" << DbU::getValueString(fsm.getCost(itrack).getTrack()->getAxis()) cdebug_log(159,0) << "Placed: @" << DbU::getValueString(fsm.getTrack1(itrack)->getAxis())
<< " " << this << endl; << " " << this << endl;
} }
@ -541,10 +541,10 @@ namespace Katana {
if ( _segment->getTrack() if ( _segment->getTrack()
and fsm.getCosts().size() and fsm.getCosts().size()
and fsm.getCost(0).isFree() and fsm.getCost(0)->isFree()
and (fsm.getCost(0).getTrack() != _segment->getTrack()) ) { and (fsm.getTrack1(0) != _segment->getTrack()) ) {
cerr << "_processPack(): move to " << fsm.getCost(0).getTrack() << endl; cerr << "_processPack(): move to " << fsm.getTrack1(0) << endl;
fsm.moveToTrack( 0 ); fsm.moveToTrack( 0 );
} }
} }
@ -569,7 +569,7 @@ namespace Katana {
cdebug_log(159,0) << "| " << fsm.getCost(i) << endl; cdebug_log(159,0) << "| " << fsm.getCost(i) << endl;
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
if (fsm.getCosts().size() and fsm.getCost(0).isFree()) { if (fsm.getCosts().size() and fsm.getCost(0)->isFree()) {
cdebug_log(159,0) << "Insert in free space." << endl; cdebug_log(159,0) << "Insert in free space." << endl;
fsm.bindToTrack( 0 ); fsm.bindToTrack( 0 );
} else { } else {

View File

@ -36,26 +36,6 @@ namespace {
using namespace Katana; using namespace Katana;
// -------------------------------------------------------------------
// Class : "CompareCostArray".
class CompareCostArray {
public:
inline CompareCostArray ( uint32_t flags=0 );
inline bool operator() ( const array<TrackCost,2>& lhs, const array<TrackCost,2>& rhs );
private:
TrackCost::Compare _compare;
};
inline CompareCostArray::CompareCostArray ( uint32_t flags )
: _compare(flags)
{ }
inline bool CompareCostArray::operator() ( const array<TrackCost,2>& lhs, const array<TrackCost,2>& rhs )
{ return _compare( lhs[0], rhs[0] ); }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "Cs1Candidate". // Class : "Cs1Candidate".
@ -479,7 +459,6 @@ namespace Katana {
DataSymmetric* symData = NULL; DataSymmetric* symData = NULL;
TrackElement* segment1 = _event1->getSegment(); TrackElement* segment1 = _event1->getSegment();
TrackElement* segment2 = segment1->getSymmetric(); TrackElement* segment2 = segment1->getSymmetric();
uint32_t depth = Session::getRoutingGauge()->getLayerDepth(segment1->getLayer());
_event1->setTracksFree( 0 ); _event1->setTracksFree( 0 );
_data1 = segment1->getDataNegociate(); _data1 = segment1->getDataNegociate();
@ -562,58 +541,20 @@ namespace Katana {
// if ( segment->isLocal() and (_data->getState() >= DataNegociate::MaximumSlack) ) // if ( segment->isLocal() and (_data->getState() >= DataNegociate::MaximumSlack) )
// _constraint.inflate ( 0, DbU::lambda(1.0) ); // _constraint.inflate ( 0, DbU::lambda(1.0) );
bool inLocalDepth = (depth < 3);
bool isOneLocalTrack = (segment1->isLocal())
and (segment1->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0);
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment1->getLayer()); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment1->getLayer());
for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) { for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) {
uint32_t costflags = 0;
costflags |= (segment1->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0;
costflags |= (segment1->isAnalog()) ? TrackCost::Analog : 0;
Track* track2 = NULL; Track* track2 = NULL;
if (_event2) { if (_event2) {
track2 = track2 =
(_sameAxis) ? track1 : plane->getTrackByPosition( symData->getSymmetrical( track1->getAxis() ) ); (_sameAxis) ? track1 : plane->getTrackByPosition( symData->getSymmetrical( track1->getAxis() ) );
} }
_costs.push_back( array<TrackCost,2>( { TrackCost(NULL), TrackCost(NULL) } ) ); _costs.push_back( new TrackCost(segment1,segment2,track1,track2) );
if (not segment1->isReduced()) {
_costs.back()[0] = track1->getOverlapCost(segment1,costflags);
if (_event2) _costs.back()[1] = track2->getOverlapCost(segment2,costflags);
} else {
_costs.back()[0] = TrackCost(track1);
if (_event2) _costs.back()[1] = TrackCost(track2);
}
_costs.back()[0].setAxisWeight ( _event1->getAxisWeight(track1->getAxis()) ); if ( _fullBlocked and (not _costs.back()->isBlockage() and not _costs.back()->isFixed()) )
_costs.back()[0].incDeltaPerpand( _data1->getWiringDelta(track1->getAxis()) );
if (_event2) {
_costs.back()[1].setAxisWeight ( _event2->getAxisWeight(track2->getAxis()) );
_costs.back()[1].incDeltaPerpand( _data2->getWiringDelta(track2->getAxis()) );
_costs.back()[0].merge( _costs.back()[1] );
}
if (segment1->isGlobal()) {
cdebug_log(9000,0) << "Deter| setForGlobal() on " << track1 << endl;
_costs.back()[0].setForGlobal();
}
if ( inLocalDepth and (_costs.back()[0].getDataState() == DataNegociate::MaximumSlack) )
_costs.back()[0].setInfinite();
if ( isOneLocalTrack
and _costs.back()[0].isOverlapGlobal()
and (_costs.back()[0].getDataState() >= DataNegociate::ConflictSolveByHistory) )
_costs.back()[0].setInfinite();
_costs.back()[0].consolidate();
if ( _fullBlocked and (not _costs.back()[0].isBlockage() and not _costs.back()[0].isFixed()) )
_fullBlocked = false; _fullBlocked = false;
cdebug_log(155,0) << "| " << _costs.back()[0] << ((_fullBlocked)?" FB ": " -- ") << track1 << endl; cdebug_log(155,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track1 << endl;
} }
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
@ -648,16 +589,18 @@ namespace Katana {
// FOR ANALOG ONLY. // FOR ANALOG ONLY.
//flags |= TrackCost::IgnoreSharedLength; //flags |= TrackCost::IgnoreSharedLength;
sort( _costs.begin(), _costs.end(), CompareCostArray(flags) ); sort( _costs.begin(), _costs.end(), TrackCost::Compare(flags) );
size_t i=0; size_t i=0;
for ( ; (i<_costs.size()) and _costs[i][0].isFree() ; i++ ); for ( ; (i<_costs.size()) and _costs[i]->isFree() ; i++ );
_event1->setTracksFree ( i ); _event1->setTracksFree( i );
if (_event2) _event2->setTracksFree( i );
}
if (_event2) {
for ( ; (i<_costs.size()) and _costs[i][1].isFree() ; i++ ); SegmentFsm::~SegmentFsm ()
_event2->setTracksFree ( i ); {
} for ( TrackCost* cost : _costs ) delete cost;
} }
@ -720,7 +663,7 @@ namespace Katana {
bool SegmentFsm::insertInTrack ( size_t i ) bool SegmentFsm::insertInTrack ( size_t i )
{ {
cdebug_log(159,0) << "SegmentFsm::insertInTrack() istate:" << _event1->getInsertState() cdebug_log(159,0) << "SegmentFsm::insertInTrack() istate:" << _event1->getInsertState()
<< " track:" << i << endl; << " track:" << i << endl;
bool success = true; bool success = true;
@ -761,8 +704,8 @@ namespace Katana {
_event1->updateAxisHistory(); _event1->updateAxisHistory();
_event1->setEventLevel( 0 ); _event1->setEventLevel( 0 );
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl;
Session::addInsertEvent( getSegment1(), getCost1(i).getTrack() ); Session::addInsertEvent( getSegment1(), getTrack1(i) );
if (_event2) { if (_event2) {
_event2->resetInsertState(); _event2->resetInsertState();
@ -770,8 +713,8 @@ namespace Katana {
_event2->setEventLevel( 0 ); _event2->setEventLevel( 0 );
_event2->setProcessed( true ); _event2->setProcessed( true );
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl;
Session::addInsertEvent( getSegment2(), getCost2(i).getTrack() ); Session::addInsertEvent( getSegment2(), getTrack2(i) );
} }
setState( SegmentFsm::SelfInserted ); setState( SegmentFsm::SelfInserted );
@ -782,11 +725,11 @@ namespace Katana {
{ {
cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl; cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl;
Session::addMoveEvent( getSegment1(), getCost1(i).getTrack() ); Session::addMoveEvent( getSegment1(), getTrack1(i) );
if (_event2) { if (_event2) {
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl; cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getTrack1(i) << endl;
Session::addMoveEvent( getSegment2(), getCost2(i).getTrack() ); Session::addMoveEvent( getSegment2(), getTrack2(i) );
} }
setState( SegmentFsm::SelfInserted ); setState( SegmentFsm::SelfInserted );
@ -1045,10 +988,10 @@ namespace Katana {
Interval overlap = segment->getCanonicalInterval(); Interval overlap = segment->getCanonicalInterval();
size_t begin; size_t begin;
size_t end; size_t end;
getCost(icost).getTrack()->getOverlapBounds( overlap, begin, end ); getTrack1(icost)->getOverlapBounds( overlap, begin, end );
for ( ; begin<end ; ++begin ) { for ( ; begin<end ; ++begin ) {
TrackElement* other = getCost(icost).getTrack()->getSegment(begin); TrackElement* other = getTrack1(icost)->getSegment(begin);
Interval otherOverlap = other->getCanonicalInterval(); Interval otherOverlap = other->getCanonicalInterval();
if (other->getNet() == segment->getNet()) continue; if (other->getNet() == segment->getNet()) continue;
@ -1087,9 +1030,9 @@ namespace Katana {
size_t begin; size_t begin;
size_t end; size_t end;
getCost(0).getTrack()->getOverlapBounds ( overlap, begin, end ); getTrack1(0)->getOverlapBounds ( overlap, begin, end );
for ( ; begin<end ; ++begin ) { for ( ; begin<end ; ++begin ) {
TrackElement* other = getCost(0).getTrack()->getSegment(begin); TrackElement* other = getTrack1(0)->getSegment(begin);
Interval otherOverlap = other->getCanonicalInterval(); Interval otherOverlap = other->getCanonicalInterval();
if ( other->getNet() == segment->getNet() ) continue; if ( other->getNet() == segment->getNet() ) continue;
@ -1124,7 +1067,7 @@ namespace Katana {
for ( ; itrack<getCosts().size() ; ++itrack ) { for ( ; itrack<getCosts().size() ; ++itrack ) {
cdebug_log(159,0) << "Trying track:" << itrack << endl; cdebug_log(159,0) << "Trying track:" << itrack << endl;
if ( getCost(itrack).isGlobalEnclosed() ) { if ( getCost(itrack)->isGlobalEnclosed() ) {
Track* track = getTrack(itrack); Track* track = getTrack(itrack);
size_t begin = getBegin(itrack); size_t begin = getBegin(itrack);
size_t end = getEnd (itrack); size_t end = getEnd (itrack);
@ -1161,7 +1104,7 @@ namespace Katana {
setState ( SegmentFsm::OtherRipup ); setState ( SegmentFsm::OtherRipup );
addAction( segment addAction( segment
, SegmentAction::SelfInsert|SegmentAction::MoveToAxis , SegmentAction::SelfInsert|SegmentAction::MoveToAxis
, getCost(itrack).getTrack()->getAxis() , getTrack1(itrack)->getAxis()
); );
break; break;
} }

View File

@ -277,15 +277,16 @@ namespace Katana {
} }
TrackCost Track::getOverlapCost ( Interval interval TrackCost& Track::addOverlapCost ( TrackCost& cost ) const
, Net* net
, size_t begin
, size_t end
, uint32_t flags ) const
{ {
TrackCost cost ( const_cast<Track*>(this), interval, begin, end, net, flags ); size_t begin = Track::npos;
size_t end = Track::npos;
const Interval& interval = cost.getInterval();
cdebug_log(155,1) << "getOverlapCost() @" << DbU::getValueString(_axis) getOverlapBounds( cost.getInterval(), begin, end );
cost.setTrack( const_cast<Track*>(this), begin, end );
cdebug_log(155,1) << "addOverlapCost() @" << DbU::getValueString(_axis)
<< " [" << DbU::getValueString(interval.getVMin()) << " [" << DbU::getValueString(interval.getVMin())
<< ":" << DbU::getValueString(interval.getVMax()) << ":" << DbU::getValueString(interval.getVMax())
<< "] <-> [" << begin << ":" << end << "]" << "] <-> [" << begin << ":" << end << "]"
@ -298,7 +299,7 @@ namespace Katana {
for ( ; (mbegin < _markers.size()) for ( ; (mbegin < _markers.size())
and (_markers[mbegin]->getSourceU() <= interval.getVMax()) ; mbegin++ ) { and (_markers[mbegin]->getSourceU() <= interval.getVMax()) ; mbegin++ ) {
cdebug_log(155,0) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl; cdebug_log(155,0) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl;
if ( _markers[mbegin]->getNet() != net ) { if (_markers[mbegin]->getNet() != cost.getNet()) {
cdebug_log(155,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl; cdebug_log(155,0) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl;
cost.incTerminals( _markers[mbegin]->getWeight(this) ); cost.incTerminals( _markers[mbegin]->getWeight(this) );
} }
@ -312,12 +313,12 @@ namespace Katana {
for ( ; begin < end ; begin++ ) { for ( ; begin < end ; begin++ ) {
Interval overlap = interval.getIntersection( _segments[begin]->getCanonicalInterval() ); Interval overlap = interval.getIntersection( _segments[begin]->getCanonicalInterval() );
if ( _segments[begin]->getNet() == net ) { if (_segments[begin]->getNet() == cost.getNet()) {
cdebug_log(155,0) << "overlap:" << overlap << " size:" << overlap.getSize() << endl; cdebug_log(155,0) << "overlap:" << overlap << " size:" << overlap.getSize() << endl;
cost.incDeltaShared ( overlap.getSize() ); cost.incDeltaShared ( overlap.getSize() );
} }
_segments[begin]->incOverlapCost( net, cost ); _segments[begin]->incOverlapCost( cost );
cdebug_log(155,0) << "| overlap: " << _segments[begin] << " cost:" << cost << endl; cdebug_log(155,0) << "| overlap: " << _segments[begin] << " cost:" << &cost << endl;
if (cost.isInfinite()) break; if (cost.isInfinite()) break;
} }
@ -328,21 +329,6 @@ namespace Katana {
} }
TrackCost Track::getOverlapCost ( Interval interval, Net* net, uint32_t flags ) const
{
size_t begin;
size_t end;
getOverlapBounds( interval, begin, end );
return getOverlapCost( interval, net, begin, end, flags );
}
TrackCost Track::getOverlapCost ( TrackElement* segment, uint32_t flags ) const
{ return getOverlapCost ( segment->getCanonicalInterval(), segment->getNet(), flags ); }
void Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, uint32_t& weight ) const void Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, uint32_t& weight ) const
{ {
cdebug_log(155,1) << "getTerminalWeight() @" << DbU::getValueString(_axis) cdebug_log(155,1) << "getTerminalWeight() @" << DbU::getValueString(_axis)
@ -468,10 +454,10 @@ namespace Katana {
,getString(segment).c_str()) << endl; ,getString(segment).c_str()) << endl;
} }
segment->setAxis ( getAxis() );
_segments.push_back ( segment ); _segments.push_back ( segment );
_segmentsValid = false; _segmentsValid = false;
//segment->setAxis ( getAxis() );
segment->setTrack ( this ); segment->setTrack ( this );
} }

View File

@ -19,6 +19,7 @@
#include <iostream> #include <iostream>
#include "katana/Track.h" #include "katana/Track.h"
#include "katana/TrackCost.h" #include "katana/TrackCost.h"
#include "katana/TrackElement.h"
#include "katana/Session.h" #include "katana/Session.h"
@ -26,63 +27,27 @@ namespace Katana {
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using Hurricane::Error;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "TrackCost". // Class : "TrackCost".
TrackCost::TrackCost ( Track* track ) TrackCost::TrackCost ( TrackElement* refSegment
: _flags (ZeroCost) , TrackElement* symSegment
, _track (track) , Track* refTrack
, _begin (Track::npos) , Track* symTrack
, _end (Track::npos)
, _interval ()
, _forGlobal (false)
, _blockage (false)
, _fixed (false)
, _infinite (false)
, _hardOverlap (false)
, _overlap (false)
, _leftOverlap (false)
, _rightOverlap (false)
, _overlapGlobal (false)
, _globalEnclosed (false)
, _terminals (0)
, _delta (0)
, _deltaShared (0)
, _deltaPerpand (0)
, _axisWeight (0)
, _distanceToFixed(2*Session::getSliceHeight())
, _longuestOverlap(0)
, _dataState (0)
, _ripupCount (0)
{ }
TrackCost::TrackCost ( Track* track
, const Interval& interval
, size_t begin
, size_t end
, Net* net
, uint32_t flags
) )
: _flags (flags) : _flags ((symSegment) ? Symmetric : NoFlags)
, _track (track) , _span (1)
, _begin (begin) , _tracks ( _span * ((symSegment) ? 2 : 1)
, _end (end) , std::tuple<Track*,size_t,size_t>(NULL,Track::npos,Track::npos) )
, _interval (interval) , _segment1 (refSegment)
, _forGlobal (false) , _segment2 (symSegment)
, _blockage (false) , _interval1 (refSegment->getCanonicalInterval())
, _fixed (false) , _interval2 ((symSegment) ? symSegment->getCanonicalInterval() : Interval())
, _infinite (false)
, _hardOverlap (false)
, _overlap (false)
, _leftOverlap (false)
, _rightOverlap (false)
, _overlapGlobal (false)
, _globalEnclosed (false)
, _terminals (0) , _terminals (0)
, _delta (-interval.getSize()) , _delta (-_interval1.getSize() -_interval2.getSize())
, _deltaShared (0) , _deltaShared (0)
, _deltaPerpand (0) , _deltaPerpand (0)
, _axisWeight (0) , _axisWeight (0)
@ -90,94 +55,76 @@ namespace Katana {
, _longuestOverlap(0) , _longuestOverlap(0)
, _dataState (0) , _dataState (0)
, _ripupCount (0) , _ripupCount (0)
, _selectFlags (NoFlags)
, _selectIndex (0)
{ {
if (not (_flags & Analog)) { std::get<0>( _tracks[0] ) = refTrack;
// This is the GCell side (it is *one* cell height from the gauge). _segment1->addOverlapCost( *this );
DbU::Unit cellHeight = Session::getSliceHeight();
TrackElement* neighbor; if (symTrack) {
if ( _begin != Track::npos ) { std::get<0>( _tracks[_span] ) = symTrack;
neighbor = _track->getSegment(_begin); select( 0, Symmetric );
if ( neighbor and (neighbor->getNet() != net) ) { _segment2->addOverlapCost( *this );
DbU::Unit distance = interval.getVMin() - neighbor->getTargetU();
if ( distance < cellHeight )
_distanceToFixed = distance;
}
// if ( neighbor and neighbor->isFixed() ) {
// if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0;
// _distanceToFixed += interval.getVMin() - neighbor->getTargetU();
// }
}
if ( _end != Track::npos ) {
neighbor = _track->getSegment(_end);
if ( neighbor and (neighbor->getNet() != net) ) {
DbU::Unit distance = neighbor->getSourceU() - interval.getVMax();
if ( _distanceToFixed == 2*cellHeight ) _distanceToFixed = 0;
if ( distance < cellHeight )
_distanceToFixed += distance;
}
// if ( neighbor and neighbor->isFixed() ) {
// if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0;
// _distanceToFixed += neighbor->getSourceU() - interval.getVMax();
// }
}
} }
consolidate();
} }
TrackCost::~TrackCost () TrackCost::~TrackCost ()
{ } { }
bool TrackCost::isFree () const bool TrackCost::isFree () const
{ {
return /*(not _terminals) and*/ (not _overlap) and (not _infinite); return /*(not _terminals) and*/ (not isOverlap()) and (not isInfinite());
} }
bool TrackCost::Compare::operator() ( const TrackCost& lhs, const TrackCost& rhs ) bool TrackCost::Compare::operator() ( const TrackCost* lhs, const TrackCost* rhs )
{ {
if ( lhs._infinite xor rhs._infinite ) return rhs._infinite; if ( lhs->isInfinite() xor rhs->isInfinite() ) return rhs->isInfinite();
if ( (_flags & TrackCost::DiscardGlobals) if ( (_flags & TrackCost::DiscardGlobals)
and (lhs._overlapGlobal xor rhs._overlapGlobal) ) and (lhs->isOverlapGlobal() xor rhs->isOverlapGlobal()) )
return rhs._overlapGlobal; return rhs->isOverlapGlobal();
if ( lhs._hardOverlap xor rhs._hardOverlap ) return rhs._hardOverlap; 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;
//if ( lhsRipupCost + (int)Session::getRipupCost() < rhsRipupCost ) return true; //if ( lhsRipupCost + (int)Session::getRipupCost() < rhsRipupCost ) return true;
//if ( lhsRipupCost > (int)Session::getRipupCost() + rhsRipupCost ) return false; //if ( lhsRipupCost > (int)Session::getRipupCost() + rhsRipupCost ) return false;
//if ( _flags & TrackCost::DiscardGlobals ) { //if ( _flags & TrackCost::DiscardGlobals ) {
// if ( lhs._longuestOverlap < rhs._longuestOverlap ) return true; // if ( lhs->_longuestOverlap < rhs->_longuestOverlap ) return true;
// if ( lhs._longuestOverlap > rhs._longuestOverlap ) return false; // if ( lhs->_longuestOverlap > rhs->_longuestOverlap ) return false;
//} //}
if ( lhs._overlap xor rhs._overlap ) return rhs._overlap; if ( lhs->isOverlap() xor rhs->isOverlap() ) return rhs->isOverlap();
if ( lhs._terminals < rhs._terminals ) return true; if ( lhs->_terminals < rhs->_terminals ) return true;
if ( lhs._terminals > rhs._terminals ) return false; if ( lhs->_terminals > rhs->_terminals ) return false;
if (lhs._delta != rhs._delta) { if (lhs->_delta != rhs->_delta) {
//cdebug_log(155,0) << "TrackCost::Compare() lhs._delta:" << lhs._delta << " rhs._delta:" << rhs._delta << endl; //cdebug_log(155,0) << "TrackCost::Compare() lhs->_delta:" << lhs->_delta << " rhs->_delta:" << rhs->_delta << endl;
//if ( not (_flags & TrackCost::IgnoreSharedLength) or (lhs._delta > 0) or (rhs._delta > 0) ) { //if ( not (_flags & TrackCost::IgnoreSharedLength) or (lhs->_delta > 0) or (rhs->_delta > 0) ) {
//if ( (lhs._delta > 0) or (rhs._delta > 0) ) { //if ( (lhs->_delta > 0) or (rhs->_delta > 0) ) {
if (lhs._delta < rhs._delta) return true; if (lhs->_delta < rhs->_delta) return true;
if (lhs._delta > rhs._delta) return false; if (lhs->_delta > rhs->_delta) return false;
//} //}
// Both delta should be negative, chose the least one. // Both delta should be negative, chose the least one.
//return lhs._delta > rhs._delta; //return lhs->_delta > rhs->_delta;
return lhs._delta < rhs._delta; return lhs->_delta < rhs->_delta;
} }
#if 0 #if 0
DbU::Unit lhsMixedWeight = 0.5*lhs._deltaPerpand; DbU::Unit lhsMixedWeight = 0.5*lhs->_deltaPerpand;
DbU::Unit rhsMixedWeight = 0.5*rhs._deltaPerpand; DbU::Unit rhsMixedWeight = 0.5*rhs->_deltaPerpand;
if ( not (_flags & TrackCost::IgnoreAxisWeight) ) { if ( not (_flags & TrackCost::IgnoreAxisWeight) ) {
lhsMixedWeight += lhsMixedWeight; lhsMixedWeight += lhsMixedWeight;
@ -189,29 +136,46 @@ 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()->getAxis() < rhs.getTrack()->getAxis(); return lhs->getTrack(0)->getAxis() < rhs->getTrack(0)->getAxis();
} }
bool TrackCost::CompareByDelta::operator() ( const TrackCost& lhs, const TrackCost& rhs ) bool TrackCost::CompareByDelta::operator() ( const TrackCost* lhs, const TrackCost* rhs )
{ {
return lhs.getDelta() < rhs.getDelta(); return lhs->getDelta() < rhs->getDelta();
}
Net* TrackCost::getNet1 () const { return (_segment1) ? _segment1->getNet() : NULL; }
Net* TrackCost::getNet2 () const { return (_segment2) ? _segment2->getNet() : NULL; }
size_t TrackCost::getBegin ( size_t i, uint32_t flags ) const
{
if (i >= _span) return Track::npos;
return std::get<1>( _tracks[i + ((flags & Symmetric) ? _span : 0)] );
}
size_t TrackCost::getEnd ( size_t i, uint32_t flags ) const
{
if (i >= _span) return Track::npos;
return std::get<2>( _tracks[i + ((flags & Symmetric) ? _span : 0)] );
} }
void TrackCost::consolidate () void TrackCost::consolidate ()
{ {
if ( not _infinite and not _hardOverlap ) { if ( not isInfinite() and not isHardOverlap() ) {
cdebug_log(159,0) << "TrackCost::consolidate() " << _delta << " - " << _deltaShared << endl; cdebug_log(159,0) << "TrackCost::consolidate() " << _delta << " - " << _deltaShared << endl;
//_deltaPerpand += - (_deltaShared << 1); //_deltaPerpand += - (_deltaShared << 1);
_delta -= _deltaShared; _delta -= _deltaShared;
@ -221,16 +185,41 @@ namespace Katana {
} }
void TrackCost::merge ( const TrackCost& other ) void TrackCost::setDistanceToFixed ()
{ {
_terminals += other._terminals; if (_flags & Analog) return;
_delta += other._delta;
_deltaShared += other._deltaShared; // This is the GCell side (it is *one* cell height from the gauge).
_deltaPerpand += other._deltaPerpand; DbU::Unit cellHeight = Session::getSliceHeight();
_axisWeight += other._axisWeight;
_distanceToFixed = std::min( _distanceToFixed, other._distanceToFixed ); cdebug_log(159,0) << "TrackCost::setDistanceToFixed() begin:" << getBegin(0) << endl;
_longuestOverlap = std::min( _longuestOverlap, other._longuestOverlap );
_dataState = std::max( _dataState, other._dataState ); TrackElement* neighbor;
if (getBegin(0) != Track::npos) {
neighbor = getTrack(0)->getSegment(getBegin(0));
if ( neighbor and (neighbor->getNet() != getNet()) ) {
DbU::Unit distance = getInterval().getVMin() - neighbor->getTargetU();
if ( distance < cellHeight )
_distanceToFixed = distance;
}
// if ( neighbor and neighbor->isFixed() ) {
// if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0;
// _distanceToFixed += _interval.getVMin() - neighbor->getTargetU();
// }
}
if (getEnd(0) != Track::npos) {
neighbor = getTrack(0)->getSegment(getEnd(0));
if ( neighbor and (neighbor->getNet() != getNet()) ) {
DbU::Unit distance = neighbor->getSourceU() - getInterval().getVMax();
if ( _distanceToFixed == 2*cellHeight ) _distanceToFixed = 0;
if ( distance < cellHeight )
_distanceToFixed += distance;
}
// if ( neighbor and neighbor->isFixed() ) {
// if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0;
// _distanceToFixed += neighbor->getSourceU() - _interval.getVMax();
// }
}
} }
@ -238,25 +227,25 @@ namespace Katana {
{ {
string s = "<" + _getTypeName(); string s = "<" + _getTypeName();
s += " " + getString(_track); s += " " + getString(getTrack(0));
s += " " + getString(_dataState); s += " " + getString(_dataState);
s += "+" + getString(_ripupCount); s += "+" + getString(_ripupCount);
s += ":" + getString((_dataState<<2)+_ripupCount); s += ":" + getString((_dataState<<2)+_ripupCount);
s += " " + string ( (_infinite )?"I":"-" ); s += " " + string ( (isInfinite() )?"I":"-" );
s += string ( (_blockage )?"b":"-" ); s += string ( (isBlockage() )?"b":"-" );
s += string ( (_fixed )?"f":"-" ); s += string ( (isFixed() )?"f":"-" );
s += string ( (_hardOverlap )?"h":"-" ); s += string ( (isHardOverlap() )?"h":"-" );
s += string ( (_overlap )?"o":"-" ); s += string ( (isOverlap() )?"o":"-" );
s += string ( (_overlapGlobal )?"g":"-" ); s += string ( (isOverlapGlobal() )?"g":"-" );
s += string ( (_globalEnclosed)?"e":"-" ); s += string ( (isGlobalEnclosed())?"e":"-" );
s += " " + getString(_terminals); s += " " + getString(_terminals);
s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta); s += "/" + /*DbU::getValueString(_delta)*/ getString(_delta);
s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared); s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared);
s += "/" + DbU::getValueString(_axisWeight); s += "/" + DbU::getValueString(_axisWeight);
s += "/" + DbU::getValueString(_deltaPerpand); s += "/" + DbU::getValueString(_deltaPerpand);
s += "/f:" + DbU::getValueString(_distanceToFixed); s += "/f:" + DbU::getValueString(_distanceToFixed);
s += "/" + DbU::getValueString(_longuestOverlap); s += "/" + DbU::getValueString(_longuestOverlap);
s += " " + getString(_dataState); s += " " + getString(_dataState);
s += ">"; s += ">";
return s; return s;
@ -266,12 +255,10 @@ namespace Katana {
Record* TrackCost::_getRecord () const Record* TrackCost::_getRecord () const
{ {
Record* record = new Record ( _getString() ); Record* record = new Record ( _getString() );
record->add( getSlot ( "_track" , _track ) ); record->add( getSlot ( "_flags" , _flags ) );
record->add( getSlot ( "_begin" , &_begin ) ); record->add( getSlot ( "_tracks" , _tracks ) );
record->add( getSlot ( "_end" , &_end ) ); record->add( getSlot ( "_interval1" , &_interval1 ) );
record->add( getSlot ( "_interval" , &_interval ) ); record->add( getSlot ( "_interval2" , &_interval2 ) );
record->add( getSlot ( "_infinite" , _infinite ) );
record->add( getSlot ( "_overlap" , _overlap ) );
record->add( getSlot ( "_terminals" , _terminals ) ); record->add( getSlot ( "_terminals" , _terminals ) );
record->add( DbU::getValueSlot( "_delta" , &_delta ) ); record->add( DbU::getValueSlot( "_delta" , &_delta ) );
record->add( DbU::getValueSlot( "_deltaShared" , &_deltaShared ) ); record->add( DbU::getValueSlot( "_deltaShared" , &_deltaShared ) );

View File

@ -256,9 +256,9 @@ namespace Katana {
} }
void TrackElement::incOverlapCost ( Net* net, TrackCost& cost ) const void TrackElement::incOverlapCost ( TrackCost& cost ) const
{ {
if (not _track or (getNet() == net)) return; if (not _track or (getNet() == cost.getNet())) return;
_overlapCostCallback( this, cost ); _overlapCostCallback( this, cost );
} }

View File

@ -140,6 +140,7 @@ namespace Katana {
Flags TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); } Flags TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); }
const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); } const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); }
Interval TrackFixedSegment::getFreeInterval () const { return Interval(); } Interval TrackFixedSegment::getFreeInterval () const { return Interval(); }
size_t TrackFixedSegment::getTrackSpan () const { return 1; }
unsigned long TrackFixedSegment::getId () const unsigned long TrackFixedSegment::getId () const
@ -172,6 +173,15 @@ namespace Katana {
} }
void TrackFixedSegment::addOverlapCost ( TrackCost& cost ) const
{
Track* track = cost.getTrack();
if (not track) return;
track->addOverlapCost( cost );
}
float TrackFixedSegment::getPriority () const float TrackFixedSegment::getPriority () const
{ return 0.0; } { return 0.0; }

View File

@ -26,7 +26,8 @@
#include "anabatic/GCell.h" #include "anabatic/GCell.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "katana/DataNegociate.h" #include "katana/DataNegociate.h"
#include "katana/TrackSegment.h" #include "katana/TrackSegmentRegular.h"
#include "katana/TrackSegmentWide.h"
#include "katana/Track.h" #include "katana/Track.h"
#include "katana/Session.h" #include "katana/Session.h"
#include "katana/RoutingEvent.h" #include "katana/RoutingEvent.h"
@ -69,8 +70,8 @@ namespace Katana {
, _dogLegLevel (0) , _dogLegLevel (0)
, _flags (NoFlags) , _flags (NoFlags)
{ {
cdebug_log(155,0) << "CTOR TrackSegment " << (void*)this << ":" << this << endl; cdebug_log(155,0) << "CTOR TrackSegment " << /*(void*)this <<*/ ":" << this << endl;
cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl; cdebug_log(155,0) << " over " << /*(void*)segment <<*/ ":" << segment << endl;
setFlags( TElemCreated|TElemLocked ); setFlags( TElemCreated|TElemLocked );
if (segment) { if (segment) {
@ -129,16 +130,23 @@ namespace Katana {
{ {
created = false; created = false;
TrackElement* trackElement = Session::lookup( segment->base() ); DbU::Unit defaultWireWidth = Session::getWireWidth( segment->base()->getLayer() );
TrackElement* trackElement = Session::lookup( segment->base() );
if (not trackElement) { if (not trackElement) {
TrackSegment* trackSegment = new TrackSegment( segment, track ); if (segment->base()->getWidth() <= defaultWireWidth) {
trackSegment->_postCreate(); trackElement = new TrackSegmentRegular( segment, track );
created = true; trackElement->_postCreate();
created = true;
trackSegment->invalidate(); trackElement->invalidate();
cdebug_log(159,0) << "TrackSegment::create(): " << trackSegment << endl; cdebug_log(159,0) << "TrackSegment::create(): " << trackElement << endl;
trackElement = trackSegment; } else {
throw Error( "TrackSegment::create() Non-regular TrackSegment are not supported yet.\n"
" (on: %s)"
, getString(segment).c_str()
);
}
} }
return trackElement; return trackElement;
@ -356,7 +364,10 @@ namespace Katana {
void TrackSegment::setTrack ( Track* track ) void TrackSegment::setTrack ( Track* track )
{ TrackElement::setTrack( track ); } {
if (track) setAxis( track->getAxis(), Anabatic::SegAxisSet );
TrackElement::setTrack( track );
}
void TrackSegment::setSymmetric ( TrackElement* segment ) void TrackSegment::setSymmetric ( TrackElement* segment )

View File

@ -0,0 +1,111 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./TrackSegmentRegular.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include <limits>
#include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Net.h"
#include "hurricane/Name.h"
#include "hurricane/RoutingPad.h"
#include "anabatic/AutoContact.h"
#include "anabatic/GCell.h"
#include "crlcore/RoutingGauge.h"
#include "katana/DataNegociate.h"
#include "katana/TrackSegmentRegular.h"
#include "katana/Track.h"
#include "katana/Session.h"
#include "katana/RoutingEvent.h"
#include "katana/NegociateWindow.h"
#include "katana/KatanaEngine.h"
namespace Katana {
using namespace std;
using Hurricane::tab;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::BasicLayer;
using Hurricane::Net;
using Hurricane::Name;
using Hurricane::RoutingPad;
using Anabatic::SegSlackened;
using Anabatic::perpandicularTo;
// -------------------------------------------------------------------
// Class : "TrackSegmentRegular".
TrackSegmentRegular::TrackSegmentRegular ( AutoSegment* segment, Track* track )
: Super(segment,track)
{
// cdebug_log(155,0) << "CTOR TrackSegmentRegular " << (void*)this << ":" << this << endl;
// cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl;
}
void TrackSegmentRegular::_postCreate ()
{
Super::_postCreate();
}
TrackSegmentRegular::~TrackSegmentRegular ()
{
}
void TrackSegmentRegular::_preDestroy ()
{
Super::_preDestroy();
}
size_t TrackSegmentRegular::getTrackSpan () const { return 1; }
void TrackSegmentRegular::addOverlapCost ( TrackCost& cost ) const
{
uint32_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer());
bool inLocalDepth = (depth < 3);
bool isOneLocalTrack = (isLocal()) and (base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0);
Track* track = cost.getTrack();
if (not track) return;
cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 );
cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 );
track->addOverlapCost( cost );
cost.setDistanceToFixed();
cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) );
cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) );
if (isGlobal()) cost.setForGlobal();
if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) )
cost.setInfinite();
if ( isOneLocalTrack
and cost.isOverlapGlobal()
and (cost.getDataState() >= DataNegociate::ConflictSolveByHistory) )
cost.setInfinite();
}
} // Katana namespace.

View File

@ -0,0 +1,121 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./TrackSegmentWide.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include <limits>
#include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Net.h"
#include "hurricane/Name.h"
#include "hurricane/RoutingPad.h"
#include "anabatic/AutoContact.h"
#include "anabatic/GCell.h"
#include "crlcore/RoutingGauge.h"
#include "katana/DataNegociate.h"
#include "katana/TrackSegmentWide.h"
#include "katana/Track.h"
#include "katana/Session.h"
#include "katana/RoutingEvent.h"
#include "katana/NegociateWindow.h"
#include "katana/KatanaEngine.h"
namespace Katana {
using namespace std;
using Hurricane::tab;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::BasicLayer;
using Hurricane::Net;
using Hurricane::Name;
using Hurricane::RoutingPad;
using Anabatic::SegSlackened;
using Anabatic::perpandicularTo;
// -------------------------------------------------------------------
// Class : "TrackSegmentWide".
TrackSegmentWide::TrackSegmentWide ( AutoSegment* segment, Track* track, size_t trackSpan )
: Super(segment,track)
, _trackSpan(trackSpan)
{
cdebug_log(155,0) << "CTOR TrackSegmentWide " << (void*)this << ":" << this << endl;
cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl;
if (not _trackSpan) {
DbU::Unit mWidth = std::max( Session::getWireWidth(getLayer()), Session::getViaWidth(getLayer()) );
if (segment->getWidth() < mWidth) {
_trackSpan = 1;
} else {
_trackSpan = ((segment->getWidth() - mWidth) / Session::getPitch(segment->getLayer())) + 2;
}
}
}
void TrackSegmentWide::_postCreate ()
{
Super::_postCreate();
}
TrackSegmentWide::~TrackSegmentWide ()
{
}
void TrackSegmentWide::_preDestroy ()
{
Super::_preDestroy();
}
size_t TrackSegmentWide::getTrackSpan () const { return _trackSpan; }
void TrackSegmentWide::addOverlapCost ( TrackCost& cost ) const
{
uint32_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer());
bool inLocalDepth = (depth < 3);
Track* track = cost.getTrack();
if (not track) return;
cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 );
cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 );
for ( size_t span=0 ; (span < _trackSpan) and (track != NULL) ; ++span ) {
track->addOverlapCost( cost );
// Todo: have to choose here wether we go *next* or *previous* according
// to the symmetry kind.
track = track->getNextTrack();
}
cost.setDistanceToFixed();
cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) );
cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) );
if (isGlobal()) cost.setForGlobal();
if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) )
cost.setInfinite();
}
} // Katana namespace.

View File

@ -17,12 +17,10 @@
#ifndef KATANA_SEGMENT_FSM_H #ifndef KATANA_SEGMENT_FSM_H
#define KATANA_SEGMENT_FSM_H #define KATANA_SEGMENT_FSM_H
#include <array>
#include "katana/TrackCost.h" #include "katana/TrackCost.h"
namespace Katana { namespace Katana {
using std::array;
class TrackElement; class TrackElement;
class DataNegociate; class DataNegociate;
class RoutingEvent; class RoutingEvent;
@ -107,111 +105,120 @@ namespace Katana {
}; };
public: public:
SegmentFsm ( RoutingEvent* SegmentFsm ( RoutingEvent*
, RoutingEventQueue& , RoutingEventQueue&
, RoutingEventHistory& , RoutingEventHistory&
); );
inline bool isFullBlocked () const; ~SegmentFsm ();
inline bool isSymmetric () const; inline bool isFullBlocked () const;
inline RoutingEvent* getEvent () const; inline bool isSymmetric () const;
inline RoutingEvent* getEvent1 () const; inline RoutingEvent* getEvent () const;
inline RoutingEvent* getEvent2 () const; inline RoutingEvent* getEvent1 () const;
inline RoutingEventQueue& getQueue () const; inline RoutingEvent* getEvent2 () const;
inline RoutingEventHistory& getHistory () const; inline RoutingEventQueue& getQueue () const;
inline TrackElement* getSegment1 () const; inline RoutingEventHistory& getHistory () const;
inline TrackElement* getSegment2 () const; inline TrackElement* getSegment1 () const;
inline uint32_t getState () const; inline TrackElement* getSegment2 () const;
inline DataNegociate* getData (); inline uint32_t getState () const;
inline DataNegociate* getData1 (); inline DataNegociate* getData ();
inline DataNegociate* getData2 (); inline DataNegociate* getData1 ();
inline Interval& getConstraint (); inline DataNegociate* getData2 ();
inline Interval& getOptimal (); inline Interval& getConstraint ();
inline vector< array<TrackCost,2> >& getCosts (); inline Interval& getOptimal ();
inline TrackCost& getCost ( size_t ); inline vector<TrackCost*>& getCosts ();
inline TrackCost& getCost1 ( size_t ); inline TrackCost* getCost ( size_t );
inline TrackCost& getCost2 ( size_t ); inline Track* getTrack ( size_t );
inline Track* getTrack ( size_t ); inline Track* getTrack1 ( size_t );
inline size_t getBegin ( size_t ); inline Track* getTrack2 ( size_t );
inline size_t getEnd ( size_t ); inline size_t getBegin ( size_t );
inline vector<SegmentAction>& getActions (); inline size_t getBegin1 ( size_t );
inline void setState ( uint32_t ); inline size_t getBegin2 ( size_t );
void setDataState ( uint32_t ); inline size_t getEnd ( size_t );
void addAction ( TrackElement* inline size_t getEnd1 ( size_t );
, uint32_t type inline size_t getEnd2 ( size_t );
, DbU::Unit axisHint=0 inline vector<SegmentAction>& getActions ();
, uint32_t toState =0 inline void setState ( uint32_t );
); void setDataState ( uint32_t );
void doActions (); void addAction ( TrackElement*
inline void clearActions (); , uint32_t type
inline SegmentFsm& useEvent1 (); , DbU::Unit axisHint=0
inline SegmentFsm& useEvent2 (); , uint32_t toState =0
void incRipupCount (); );
bool insertInTrack ( size_t ); void doActions ();
void bindToTrack ( size_t ); inline void clearActions ();
void moveToTrack ( size_t ); inline SegmentFsm& useEvent1 ();
void ripupPerpandiculars (); inline SegmentFsm& useEvent2 ();
bool canRipup ( uint32_t flags=0 ); void incRipupCount ();
bool conflictSolveByHistory (); bool insertInTrack ( size_t );
bool conflictSolveByPlaceds (); void bindToTrack ( size_t );
bool solveTerminalVsGlobal (); void moveToTrack ( size_t );
bool desaturate (); void ripupPerpandiculars ();
bool slackenTopology ( uint32_t flags=0 ); bool canRipup ( uint32_t flags=0 );
bool solveFullBlockages (); bool conflictSolveByHistory ();
private: bool conflictSolveByPlaceds ();
bool _slackenStrap ( TrackElement*& bool solveTerminalVsGlobal ();
, DataNegociate*& bool desaturate ();
, uint32_t flags ); bool slackenTopology ( uint32_t flags=0 );
bool _slackenLocal ( TrackElement*& bool solveFullBlockages ();
, DataNegociate*& private:
, uint32_t flags ); bool _slackenStrap ( TrackElement*&
bool _slackenGlobal ( TrackElement*& , DataNegociate*&
, DataNegociate*& , uint32_t flags );
, uint32_t flags ); bool _slackenLocal ( TrackElement*&
private: , DataNegociate*&
RoutingEvent* _event1; , uint32_t flags );
RoutingEvent* _event2; bool _slackenGlobal ( TrackElement*&
RoutingEventQueue& _queue; , DataNegociate*&
RoutingEventHistory& _history; , uint32_t flags );
uint32_t _state; private:
DataNegociate* _data1; RoutingEvent* _event1;
DataNegociate* _data2; RoutingEvent* _event2;
Interval _constraint; RoutingEventQueue& _queue;
Interval _optimal; RoutingEventHistory& _history;
vector< array<TrackCost,2> > _costs; uint32_t _state;
vector<SegmentAction> _actions; DataNegociate* _data1;
bool _fullBlocked; DataNegociate* _data2;
bool _sameAxis; Interval _constraint;
bool _useEvent2; Interval _optimal;
vector<TrackCost*> _costs;
vector<SegmentAction> _actions;
bool _fullBlocked;
bool _sameAxis;
bool _useEvent2;
}; };
inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; } inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; }
inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); }
inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; } inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; }
inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; } inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; }
inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; } inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; }
inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; }
inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; }
inline uint32_t SegmentFsm::getState () const { return _state; } inline uint32_t SegmentFsm::getState () const { return _state; }
inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); } inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); }
inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; } inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; }
inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; } inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; }
inline DataNegociate* SegmentFsm::getData1 () { return _data1; } inline DataNegociate* SegmentFsm::getData1 () { return _data1; }
inline DataNegociate* SegmentFsm::getData2 () { return _data2; } inline DataNegociate* SegmentFsm::getData2 () { return _data2; }
inline Interval& SegmentFsm::getConstraint () { return _constraint; } inline Interval& SegmentFsm::getConstraint () { return _constraint; }
inline Interval& SegmentFsm::getOptimal () { return _optimal; } inline Interval& SegmentFsm::getOptimal () { return _optimal; }
inline vector< array<TrackCost,2> >& SegmentFsm::getCosts () { return _costs; } inline vector<TrackCost*>& SegmentFsm::getCosts () { return _costs; }
inline TrackCost& SegmentFsm::getCost ( size_t i ) { return _costs[i][0]; } inline TrackCost* SegmentFsm::getCost ( size_t i ) { return _costs[i]; }
inline TrackCost& SegmentFsm::getCost1 ( size_t i ) { return _costs[i][0]; } inline Track* SegmentFsm::getTrack ( size_t i ) { return (_useEvent2) ? getTrack2(i) : getTrack1(i); }
inline TrackCost& SegmentFsm::getCost2 ( size_t i ) { return _costs[i][1]; } inline size_t SegmentFsm::getBegin ( size_t i ) { return (_useEvent2) ? getBegin2(i) : getBegin1(i); }
inline Track* SegmentFsm::getTrack ( size_t i ) { return (_useEvent2) ? _costs[i][1].getTrack() : _costs[i][0].getTrack(); } inline size_t SegmentFsm::getEnd ( size_t i ) { return (_useEvent2) ? getEnd2 (i) : getEnd1 (i); }
inline size_t SegmentFsm::getBegin ( size_t i ) { return (_useEvent2) ? _costs[i][1].getBegin() : _costs[i][0].getBegin(); } inline Track* SegmentFsm::getTrack1 ( size_t i ) { return _costs[i]->getTrack(0,TrackCost::NoFlags ); }
inline size_t SegmentFsm::getEnd ( size_t i ) { return (_useEvent2) ? _costs[i][1].getEnd () : _costs[i][0].getEnd (); } inline Track* SegmentFsm::getTrack2 ( size_t i ) { return _costs[i]->getTrack(0,TrackCost::Symmetric); }
inline vector<SegmentAction>& SegmentFsm::getActions () { return _actions; } inline size_t SegmentFsm::getBegin1 ( size_t i ) { return _costs[i]->getBegin(0,TrackCost::NoFlags ); }
inline void SegmentFsm::setState ( uint32_t state ) { _state = state; } inline size_t SegmentFsm::getBegin2 ( size_t i ) { return _costs[i]->getBegin(0,TrackCost::Symmetric); }
inline void SegmentFsm::clearActions () { _actions.clear(); } inline size_t SegmentFsm::getEnd1 ( size_t i ) { return _costs[i]->getEnd (0,TrackCost::NoFlags ); }
inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; } inline size_t SegmentFsm::getEnd2 ( size_t i ) { return _costs[i]->getEnd (0,TrackCost::Symmetric); }
inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; } inline vector<SegmentAction>& SegmentFsm::getActions () { return _actions; }
inline void SegmentFsm::setState ( uint32_t state ) { _state = state; }
inline void SegmentFsm::clearActions () { _actions.clear(); }
inline SegmentFsm& SegmentFsm::useEvent1 () { _useEvent2 = false; return *this; }
inline SegmentFsm& SegmentFsm::useEvent2 () { _useEvent2 = true ; return *this; }
} // Katana namespace. } // Katana namespace.

View File

@ -95,9 +95,7 @@ namespace Katana {
Interval expandFreeInterval ( size_t& begin, size_t& end, uint32_t state, Net* ) const; Interval expandFreeInterval ( size_t& begin, size_t& end, uint32_t state, Net* ) const;
void getBeginIndex ( DbU::Unit position, size_t& begin, uint32_t& state ) const; void getBeginIndex ( DbU::Unit position, size_t& begin, uint32_t& state ) const;
void getOverlapBounds ( Interval, size_t& begin, size_t& end ) const; void getOverlapBounds ( Interval, size_t& begin, size_t& end ) const;
TrackCost getOverlapCost ( Interval, Net*, size_t begin, size_t end, uint32_t flags ) const; TrackCost& addOverlapCost ( TrackCost& ) const;
TrackCost getOverlapCost ( Interval, Net*, uint32_t flags ) const;
TrackCost getOverlapCost ( TrackElement*, uint32_t flags ) const;
void getTerminalWeight ( Interval, Net*, size_t& count, uint32_t& weight ) const; void getTerminalWeight ( Interval, Net*, size_t& count, uint32_t& weight ) const;
DbU::Unit getSourcePosition ( size_t index ) const; DbU::Unit getSourcePosition ( size_t index ) const;
bool check ( uint32_t& overlaps, const char* message=NULL ) const; bool check ( uint32_t& overlaps, const char* message=NULL ) const;

View File

@ -18,6 +18,7 @@
#define KATANA_TRACK_COST_H #define KATANA_TRACK_COST_H
#include <string> #include <string>
#include <tuple>
#include "hurricane/Interval.h" #include "hurricane/Interval.h"
namespace Hurricane { namespace Hurricane {
class Net; class Net;
@ -32,6 +33,7 @@ namespace Katana {
using Hurricane::Interval; using Hurricane::Interval;
using Hurricane::Net; using Hurricane::Net;
class Track; class Track;
class TrackElement;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -39,36 +41,48 @@ namespace Katana {
class TrackCost { class TrackCost {
public: public:
enum Flags { IgnoreAxisWeight = (1 << 0) enum Flags { NoFlags = 0
, DiscardGlobals = (1 << 1) , IgnoreAxisWeight = (1 << 0)
, IgnoreSharedLength = (1 << 2) , DiscardGlobals = (1 << 1)
, LocalAndTopDepth = (1 << 3) , IgnoreSharedLength = (1 << 2)
, ZeroCost = (1 << 4) , LocalAndTopDepth = (1 << 3)
, Analog = (1 << 5) , ZeroCost = (1 << 4)
, Analog = (1 << 5)
, Symmetric = (1 << 6)
, ForGlobal = (1 << 7)
, Blockage = (1 << 8)
, Fixed = (1 << 9)
, Infinite = (1 << 10)
, HardOverlap = (1 << 11)
, Overlap = (1 << 12)
, LeftOverlap = (1 << 13)
, RightOverlap = (1 << 14)
, OverlapGlobal = (1 << 15)
, GlobalEnclosed = (1 << 16)
, MergeMask = ForGlobal |Blockage|Fixed |Infinite
|HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal
|GlobalEnclosed
}; };
public: public:
// Sub-Class: "CompareByDelta()". // Sub-Class: "CompareByDelta()".
class CompareByDelta { class CompareByDelta {
public: public:
bool operator() ( const TrackCost& lhs, const TrackCost& rhs ); bool operator() ( const TrackCost* lhs, const TrackCost* rhs );
}; };
class Compare { class Compare {
public: public:
inline Compare ( uint32_t flags=0 ); inline Compare ( uint32_t flags=0 );
bool operator() ( const TrackCost& lhs, const TrackCost& rhs ); bool operator() ( const TrackCost* lhs, const TrackCost* rhs );
private: private:
uint32_t _flags; uint32_t _flags;
}; };
public: public:
TrackCost ( Track* track ); TrackCost ( TrackElement* refSegment
TrackCost ( Track* track , TrackElement* symSegment
, const Interval& interval , Track* refTrack
, size_t begin , Track* symTrack
, size_t end
, Net* net
, uint32_t flags
); );
~TrackCost (); ~TrackCost ();
inline bool isForGlobal () const; inline bool isForGlobal () const;
@ -82,11 +96,25 @@ namespace Katana {
inline bool isOverlapGlobal () const; inline bool isOverlapGlobal () const;
inline bool isGlobalEnclosed () const; inline bool isGlobalEnclosed () const;
bool isFree () const; bool isFree () const;
inline bool isSymmetric () const;
inline bool isWide () const;
inline uint32_t getFlags () const; inline uint32_t getFlags () const;
inline size_t getSpan () const;
inline Net* getNet () const;
Net* getNet1 () const;
Net* getNet2 () const;
inline Track* getTrack () const; inline Track* getTrack () const;
inline size_t getBegin () const; inline size_t getBegin () const;
inline size_t getEnd () const; inline size_t getEnd () const;
inline Track* getTrack ( size_t i ) const;
inline size_t getBegin ( size_t i ) const;
inline size_t getEnd ( size_t i ) const;
inline Track* getTrack ( size_t i, uint32_t flags ) const;
size_t getBegin ( size_t i, uint32_t flags ) const;
size_t getEnd ( size_t i, uint32_t flags ) const;
inline const Interval& getInterval () const; inline const Interval& getInterval () const;
inline const Interval& getInterval1 () const;
inline const Interval& getInterval2 () const;
inline uint32_t getTerminals () const; inline uint32_t getTerminals () const;
inline DbU::Unit getDelta () const; inline DbU::Unit getDelta () const;
inline DbU::Unit getDeltaPerpand () const; inline DbU::Unit getDeltaPerpand () const;
@ -94,6 +122,8 @@ namespace Katana {
inline long getAxisWeight () const; inline long getAxisWeight () const;
inline int getRipupCount () const; inline int getRipupCount () const;
inline uint32_t getDataState () const; inline uint32_t getDataState () const;
inline uint32_t setFlags ( uint32_t );
inline void setTrack ( Track*, size_t begin, size_t end );
inline void setForGlobal (); inline void setForGlobal ();
inline void setBlockage (); inline void setBlockage ();
inline void setFixed (); inline void setFixed ();
@ -108,34 +138,29 @@ namespace Katana {
inline void incDelta ( DbU::Unit ); inline void incDelta ( DbU::Unit );
inline void incDeltaPerpand ( DbU::Unit ); inline void incDeltaPerpand ( DbU::Unit );
inline void incDeltaShared ( DbU::Unit ); inline void incDeltaShared ( DbU::Unit );
inline void setAxisWeight ( DbU::Unit ); inline void incAxisWeight ( DbU::Unit );
inline void setLonguestOverlap ( DbU::Unit ); inline void setLonguestOverlap ( DbU::Unit );
inline void mergeRipupCount ( int ); inline void mergeRipupCount ( int );
inline void mergeDataState ( uint32_t ); inline void mergeDataState ( uint32_t );
void merge ( const TrackCost& ); inline bool select ( size_t index, uint32_t flags );
void consolidate (); void consolidate ();
void setDistanceToFixed ();
Record* _getRecord () const; Record* _getRecord () const;
string _getString () const; string _getString () const;
inline string _getTypeName () const; inline string _getTypeName () const;
// Operators. private:
TrackCost ( const TrackCost& ) = delete;
TrackCost& operator= ( const TrackCost& ) = delete;
// Attributes. // Attributes.
protected: private:
uint32_t _flags; uint32_t _flags;
Track* _track; size_t _span;
size_t _begin; std::vector< std::tuple<Track*,size_t,size_t> >
size_t _end; _tracks;
Interval _interval; TrackElement* _segment1;
bool _forGlobal; TrackElement* _segment2;
bool _blockage; Interval _interval1;
bool _fixed; Interval _interval2;
bool _infinite;
bool _hardOverlap;
bool _overlap;
bool _leftOverlap;
bool _rightOverlap;
bool _overlapGlobal;
bool _globalEnclosed;
uint32_t _terminals; uint32_t _terminals;
DbU::Unit _delta; DbU::Unit _delta;
DbU::Unit _deltaShared; DbU::Unit _deltaShared;
@ -145,59 +170,101 @@ namespace Katana {
DbU::Unit _longuestOverlap; DbU::Unit _longuestOverlap;
uint32_t _dataState; uint32_t _dataState;
int _ripupCount; int _ripupCount;
uint32_t _selectFlags;
size_t _selectIndex;
}; };
// Inline Functions. // Inline Functions.
inline bool TrackCost::isForGlobal () const { return _forGlobal; } inline bool TrackCost::isForGlobal () const { return _flags & ForGlobal; }
inline bool TrackCost::isBlockage () const { return _blockage; } inline bool TrackCost::isBlockage () const { return _flags & Blockage; }
inline bool TrackCost::isFixed () const { return _fixed; } inline bool TrackCost::isFixed () const { return _flags & Fixed; }
inline bool TrackCost::isInfinite () const { return _infinite; } inline bool TrackCost::isInfinite () const { return _flags & Infinite; }
inline bool TrackCost::isOverlap () const { return _overlap; } inline bool TrackCost::isOverlap () const { return _flags & Overlap; }
inline bool TrackCost::isLeftOverlap () const { return _leftOverlap; } inline bool TrackCost::isLeftOverlap () const { return _flags & LeftOverlap; }
inline bool TrackCost::isRightOverlap () const { return _rightOverlap; } inline bool TrackCost::isRightOverlap () const { return _flags & RightOverlap; }
inline bool TrackCost::isHardOverlap () const { return _hardOverlap; } inline bool TrackCost::isHardOverlap () const { return _flags & HardOverlap; }
inline bool TrackCost::isOverlapGlobal () const { return _overlapGlobal; } inline bool TrackCost::isOverlapGlobal () const { return _flags & OverlapGlobal; }
inline bool TrackCost::isGlobalEnclosed () const { return _globalEnclosed; } inline bool TrackCost::isGlobalEnclosed () const { return _flags & GlobalEnclosed; }
inline bool TrackCost::isSymmetric () const { return _flags & Symmetric; }
inline bool TrackCost::isWide () const { return (_span > 1); }
inline uint32_t TrackCost::getFlags () const { return _flags; } inline uint32_t TrackCost::getFlags () const { return _flags; }
inline Track* TrackCost::getTrack () const { return _track; } inline size_t TrackCost::getSpan () const { return _span; }
inline size_t TrackCost::getBegin () const { return _begin; } inline Net* TrackCost::getNet () const { return (_selectFlags & Symmetric) ? getNet2() : getNet1(); }
inline size_t TrackCost::getEnd () const { return _end; } inline Track* TrackCost::getTrack () const { return getTrack(_selectIndex,_selectFlags); }
inline const Interval& TrackCost::getInterval () const { return _interval; } inline Track* TrackCost::getTrack ( size_t i ) const { return getTrack(i,NoFlags); }
inline size_t TrackCost::getBegin () const { return getBegin(_selectIndex,_selectFlags); }
inline size_t TrackCost::getBegin ( size_t i ) const { return getBegin(i,NoFlags); }
inline size_t TrackCost::getEnd () const { return getEnd (_selectIndex,_selectFlags); }
inline size_t TrackCost::getEnd ( size_t i ) const { return getEnd (i,NoFlags); }
inline const Interval& TrackCost::getInterval () const { return (_selectFlags & Symmetric) ? getInterval2() : getInterval1(); }
inline const Interval& TrackCost::getInterval1 () const { return _interval1; }
inline const Interval& TrackCost::getInterval2 () const { return _interval2; }
inline uint32_t TrackCost::getTerminals () const { return _terminals; } inline uint32_t TrackCost::getTerminals () const { return _terminals; }
inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; } inline DbU::Unit TrackCost::getLongestOverlap () const { return _longuestOverlap; }
inline DbU::Unit TrackCost::getDelta () const { return _delta; } inline DbU::Unit TrackCost::getDelta () const { return _delta; }
inline long TrackCost::getAxisWeight () const { return _axisWeight; } inline long TrackCost::getAxisWeight () const { return _axisWeight; }
inline int TrackCost::getRipupCount () const { return _ripupCount; } inline int TrackCost::getRipupCount () const { return _ripupCount; }
inline uint32_t TrackCost::getDataState () const { return _dataState; } inline uint32_t TrackCost::getDataState () const { return _dataState; }
inline void TrackCost::setForGlobal () { _forGlobal = true; } inline uint32_t TrackCost::setFlags ( uint32_t mask ) { _flags |= mask; return _flags; }
inline void TrackCost::setBlockage () { _blockage = true; } inline void TrackCost::setForGlobal () { _flags |= ForGlobal; }
inline void TrackCost::setFixed () { _fixed = true; } inline void TrackCost::setBlockage () { _flags |= Blockage; }
inline void TrackCost::setInfinite () { _infinite = true; } inline void TrackCost::setFixed () { _flags |= Fixed; }
inline void TrackCost::setOverlap () { _overlap = true; } inline void TrackCost::setInfinite () { _flags |= Infinite; }
inline void TrackCost::setLeftOverlap () { _leftOverlap = true; } inline void TrackCost::setOverlap () { _flags |= Overlap; }
inline void TrackCost::setRightOverlap () { _rightOverlap = true; } inline void TrackCost::setLeftOverlap () { _flags |= LeftOverlap; }
inline void TrackCost::setHardOverlap () { _hardOverlap = true; } inline void TrackCost::setRightOverlap () { _flags |= RightOverlap; }
inline void TrackCost::setOverlapGlobal () { _overlapGlobal = true; } inline void TrackCost::setHardOverlap () { _flags |= HardOverlap; }
inline void TrackCost::setGlobalEnclosed () { _globalEnclosed = true; } inline void TrackCost::setOverlapGlobal () { _flags |= OverlapGlobal; }
inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; } inline void TrackCost::setGlobalEnclosed () { _flags |= GlobalEnclosed; }
inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; } inline void TrackCost::incTerminals ( uint32_t terminals ) { _terminals += terminals; }
inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; } inline void TrackCost::incDelta ( DbU::Unit delta ) { _delta += delta; }
inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; } inline void TrackCost::incDeltaPerpand ( DbU::Unit delta ) { _deltaPerpand += delta; }
inline void TrackCost::setAxisWeight ( DbU::Unit weight ) { _axisWeight = weight; } inline void TrackCost::incDeltaShared ( DbU::Unit delta ) { _deltaShared += delta; }
inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = (overlap > _longuestOverlap) ? overlap : _longuestOverlap; } inline void TrackCost::incAxisWeight ( DbU::Unit weight ) { _axisWeight += weight; }
inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = (count>_ripupCount)?count:_ripupCount; } inline void TrackCost::setLonguestOverlap ( DbU::Unit overlap ) { _longuestOverlap = std::max( overlap, _longuestOverlap ); }
inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = (state>_dataState)?state:_dataState; } inline void TrackCost::mergeRipupCount ( int count ) { _ripupCount = std::max( count , _ripupCount ); }
inline void TrackCost::mergeDataState ( uint32_t state ) { _dataState = std::max( state , _dataState ); }
inline string TrackCost::_getTypeName () const { return "TrackCost"; } inline string TrackCost::_getTypeName () const { return "TrackCost"; }
inline TrackCost::Compare::Compare ( uint32_t flags ) : _flags(flags) { } inline TrackCost::Compare::Compare ( uint32_t flags ) : _flags(flags) { }
inline bool TrackCost::select ( size_t index, uint32_t flags )
{
if ( (index >= _span) or ((flags & Symmetric) and not (_flags & Symmetric)) ) {
_selectIndex = 0;
_selectFlags = NoFlags;
return false;
}
_selectIndex = index;
_selectFlags = flags;
return true;
}
inline Track* TrackCost::getTrack ( size_t i, uint32_t flags ) const
{
if (i >= _span) return NULL;
return std::get<0>( _tracks[i + ((flags & Symmetric) ? _span : 0)] );
}
inline void TrackCost::setTrack ( Track* track, size_t begin, size_t end )
{
auto& entry = _tracks[_selectIndex + ((_selectFlags & Symmetric) ? _span : 0)];
std::get<0>( entry ) = track;
std::get<1>( entry ) = begin;
std::get<2>( entry ) = end;
}
} // Katana namespace. } // Katana namespace.
INSPECTOR_V_SUPPORT(Katana::TrackCost); INSPECTOR_P_SUPPORT(Katana::TrackCost);
#endif // KATANA_TRACK_COST_H #endif // KATANA_TRACK_COST_H

View File

@ -31,6 +31,7 @@ namespace Hurricane {
#include "anabatic/AutoSegment.h" #include "anabatic/AutoSegment.h"
#include "katana/Constants.h" #include "katana/Constants.h"
#include "katana/Session.h" #include "katana/Session.h"
#include "katana/TrackCost.h"
#include "katana/TrackElements.h" #include "katana/TrackElements.h"
@ -51,6 +52,7 @@ namespace Katana {
class DataNegociate; class DataNegociate;
class Track; class Track;
class TrackCost; class TrackCost;
class TrackSegment;
typedef map<Segment*,TrackElement*> TrackElementLut; typedef map<Segment*,TrackElement*> TrackElementLut;
@ -60,15 +62,19 @@ namespace Katana {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "TrackElement". // Class : "TrackElement".
enum TrackElementFlags { TElemCreated =0x00000001 enum TrackElementFlags { TElemCreated = (1 << 0)
, TElemBlockage =0x00000002 , TElemBlockage = (1 << 1)
, TElemFixed =0x00000004 , TElemFixed = (1 << 2)
, TElemLocked =0x00000008 , TElemWide = (1 << 3)
, TElemRouted =0x00000010 , TElemLocked = (1 << 4)
, TElemSourceDogleg=0x00000020 , TElemRouted = (1 << 5)
, TElemTargetDogleg=0x00000040 , TElemSourceDogleg = (1 << 6)
, TElemRipple =0x00000080 , TElemTargetDogleg = (1 << 7)
, TElemInvalidated =0x00000100 , TElemAlignBottom = (1 << 8)
, TElemAlignCenter = (1 << 9)
, TElemAlignTop = (1 << 10)
, TElemRipple = (1 << 11)
, TElemInvalidated = (1 << 12)
}; };
@ -82,6 +88,7 @@ namespace Katana {
class TrackElement { class TrackElement {
friend class TrackSegment;
public: public:
static SegmentOverlapCostCB* setOverlapCostCB ( SegmentOverlapCostCB* ); static SegmentOverlapCostCB* setOverlapCostCB ( SegmentOverlapCostCB* );
@ -94,6 +101,7 @@ namespace Katana {
virtual bool isFixed () const; virtual bool isFixed () const;
virtual bool isHorizontal () const = 0; virtual bool isHorizontal () const = 0;
virtual bool isVertical () const = 0; virtual bool isVertical () const = 0;
inline bool isWide () const;
virtual bool isLocal () const; virtual bool isLocal () const;
virtual bool isGlobal () const; virtual bool isGlobal () const;
virtual bool isBipoint () const; virtual bool isBipoint () const;
@ -132,6 +140,7 @@ namespace Katana {
virtual const Layer* getLayer () const = 0; virtual const Layer* getLayer () const = 0;
virtual DbU::Unit getPitch () const; virtual DbU::Unit getPitch () const;
virtual DbU::Unit getPPitch () const; virtual DbU::Unit getPPitch () const;
virtual size_t getTrackSpan () const = 0;
inline Track* getTrack () const; inline Track* getTrack () const;
inline size_t getIndex () const; inline size_t getIndex () const;
virtual float getPriority () const = 0; virtual float getPriority () const = 0;
@ -157,6 +166,7 @@ namespace Katana {
virtual TrackElement* getTargetDogleg (); virtual TrackElement* getTargetDogleg ();
virtual TrackElement* getSymmetric (); virtual TrackElement* getSymmetric ();
virtual TrackElements getPerpandiculars (); virtual TrackElements getPerpandiculars ();
virtual void addOverlapCost ( TrackCost& ) const = 0;
// Mutators. // Mutators.
inline void setFlags ( uint32_t ); inline void setFlags ( uint32_t );
inline void unsetFlags ( uint32_t ); inline void unsetFlags ( uint32_t );
@ -176,7 +186,7 @@ namespace Katana {
virtual void invalidate (); virtual void invalidate ();
virtual void revalidate (); virtual void revalidate ();
virtual void updatePPitch (); virtual void updatePPitch ();
virtual void incOverlapCost ( Net*, TrackCost& ) const; virtual void incOverlapCost ( TrackCost& ) const;
virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::SegAxisSet ); virtual void setAxis ( DbU::Unit, uint32_t flags=Anabatic::SegAxisSet );
virtual TrackElement* makeDogleg (); virtual TrackElement* makeDogleg ();
inline bool makeDogleg ( Anabatic::GCell* ); inline bool makeDogleg ( Anabatic::GCell* );
@ -199,12 +209,12 @@ namespace Katana {
// Static Attributes. // Static Attributes.
static SegmentOverlapCostCB* _overlapCostCallback; static SegmentOverlapCostCB* _overlapCostCallback;
// Attributes. // Attributes.
uint32_t _flags; uint32_t _flags;
Track* _track; Track* _track;
size_t _index; size_t _index;
DbU::Unit _sourceU; DbU::Unit _sourceU;
DbU::Unit _targetU; DbU::Unit _targetU;
Observer<TrackElement> _observer; Observer<TrackElement> _observer;
protected: protected:
// Constructors & Destructors. // Constructors & Destructors.
@ -221,8 +231,9 @@ namespace Katana {
// Inline functions. // Inline functions.
inline Observer<TrackElement>* TrackElement::getObserver () { return &_observer; } inline Observer<TrackElement>* TrackElement::getObserver () { return &_observer; }
inline void TrackElement::setFlags ( uint32_t flags ) { _flags|= flags; } inline void TrackElement::setFlags ( uint32_t flags ) { _flags |= flags; }
inline void TrackElement::unsetFlags ( uint32_t flags ) { _flags&=~flags; } inline void TrackElement::unsetFlags ( uint32_t flags ) { _flags &= ~flags; }
inline bool TrackElement::isWide () const { return _flags & TElemWide; }
inline bool TrackElement::isCreated () const { return _flags & TElemCreated; } inline bool TrackElement::isCreated () const { return _flags & TElemCreated; }
inline bool TrackElement::isInvalidated () const { return _flags & TElemInvalidated; } inline bool TrackElement::isInvalidated () const { return _flags & TElemInvalidated; }
inline bool TrackElement::isBlockage () const { return _flags & TElemBlockage; } inline bool TrackElement::isBlockage () const { return _flags & TElemBlockage; }

View File

@ -50,10 +50,12 @@ namespace Katana {
virtual Flags getDirection () const; virtual Flags getDirection () const;
virtual Net* getNet () const; virtual Net* getNet () const;
virtual const Layer* getLayer () const; virtual const Layer* getLayer () const;
virtual size_t getTrackSpan () const;
virtual TrackElement* getNext () const; virtual TrackElement* getNext () const;
virtual TrackElement* getPrevious () const; virtual TrackElement* getPrevious () const;
virtual DbU::Unit getAxis () const; virtual DbU::Unit getAxis () const;
virtual Interval getFreeInterval () const; virtual Interval getFreeInterval () const;
virtual void addOverlapCost ( TrackCost& ) const;
virtual float getPriority () const; virtual float getPriority () const;
virtual void setPriorityLock ( bool ); virtual void setPriorityLock ( bool );
virtual void forcePriority ( float ); virtual void forcePriority ( float );

View File

@ -0,0 +1,68 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./katana/TrackSegmentRegular.h" |
// +-----------------------------------------------------------------+
#ifndef KATANA_TRACK_SEGMENT_REGULAR_H
#define KATANA_TRACK_SEGMENT_REGULAR_H
#include <set>
#include <functional>
#include "katana/TrackSegment.h"
namespace Katana {
using std::string;
using std::map;
using std::set;
using std::binary_function;
using Hurricane::Record;
using Hurricane::Interval;
using Hurricane::DbU;
using Hurricane::Net;
using Hurricane::Layer;
using Anabatic::AutoSegment;
class DataNegociate;
class Track;
class TrackCost;
// -------------------------------------------------------------------
// Class : "TrackSegmentRegular".
class TrackSegmentRegular : public TrackSegment {
friend class TrackSegment;
public:
typedef TrackSegment Super;
protected:
TrackSegmentRegular ( AutoSegment*, Track* ) ;
virtual ~TrackSegmentRegular ();
virtual void _postCreate ();
virtual void _preDestroy ();
virtual size_t getTrackSpan () const;
virtual void addOverlapCost ( TrackCost& ) const;
private:
TrackSegmentRegular ( const TrackSegmentRegular& ) = delete;
TrackSegmentRegular& operator= ( const TrackSegmentRegular& ) = delete;
};
} // Katana namespace.
INSPECTOR_P_SUPPORT(Katana::TrackSegmentRegular);
#endif // KATANA_TRACK_SEGMENT_REGULAR_H

View File

@ -0,0 +1,70 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./katana/TrackSegmentWide.h" |
// +-----------------------------------------------------------------+
#ifndef KATANA_TRACK_SEGMENT_WIDE_H
#define KATANA_TRACK_SEGMENT_WIDE_H
#include <set>
#include <functional>
#include "katana/TrackSegment.h"
namespace Katana {
using std::string;
using std::map;
using std::set;
using std::binary_function;
using Hurricane::Record;
using Hurricane::Interval;
using Hurricane::DbU;
using Hurricane::Net;
using Hurricane::Layer;
using Anabatic::AutoSegment;
class DataNegociate;
class Track;
class TrackCost;
// -------------------------------------------------------------------
// Class : "TrackSegmentWide".
class TrackSegmentWide : public TrackSegment {
friend class TrackSegment;
public:
typedef TrackSegment Super;
protected:
TrackSegmentWide ( AutoSegment*, Track*, size_t trackSpan=0 ) ;
virtual ~TrackSegmentWide ();
virtual void _postCreate ();
virtual void _preDestroy ();
virtual size_t getTrackSpan () const;
virtual void addOverlapCost ( TrackCost& ) const;
private:
TrackSegmentWide ( const TrackSegmentWide& ) = delete;
TrackSegmentWide& operator= ( const TrackSegmentWide& ) = delete;
private:
size_t _trackSpan;
};
} // Katana namespace.
INSPECTOR_P_SUPPORT(Katana::TrackSegmentWide);
#endif // KATANA_TRACK_SEGMENT_WIDE_H