Support for symmetric routing in Anabatic/Katabatic.

* New: In Katana::SegmentFsm, the object is now able to handle two events
    at the same time. The master and it's symmetric. When there is no
    symmetric, the corresponing data is just left blank. This makes a
    bigger object, but as there is only one when running, it is not an
    issue.
      Candidates tracks are now an vector of array<2> (pairs), the
    TrackCost::Compare() functor has to be wrapped through CompareCostArray.
    The compined TrackCost of the two tracks is accumulated into the first
    element.
      Everything related to events gets duplicated: _event is now _event1
    and _event2, and so on.
      As there can be now two Manipulator actions done with SegmentFsm,
    this class now completly hide the Manipulator level from the
    RoutingEvent processing.
      New function ::bindToTrack() to perform the track insertion.
* New: In Katana::TrackCost, add a new ::merge() function.
* New: In Katana::TrackElement and Katana::TrackSegment, add symmetric
    management. Allows to know if a TrackElement has a symmetric and to
    access it.
* New: In Katana::DataSymmetric, add new overload for ::getSymmetrical()
    to handle DbU::Unit and intervals.
* Change: In Katana::RoutingEvent, remove all direct uses of Manipulator
    objects. Now any change to the event associated segment must go through
    call to Segment Fsm.
* Change: In Katana, adjust the debug level so internal informations are
    put below level 156.
* New: In Hurricane::DbU, in ::getValueString(), special display when the
    value is Min or Max (more helpful than a gigantic number).
This commit is contained in:
Jean-Paul Chaput 2017-04-30 23:46:33 +02:00
parent 2396ff7120
commit ef69a6d586
22 changed files with 622 additions and 304 deletions

View File

@ -822,7 +822,7 @@ namespace Anabatic {
DbU::Unit optimalMax = min( max(getOptimalMax(),constraintMin), constraintMax ); DbU::Unit optimalMax = min( max(getOptimalMax(),constraintMin), constraintMax );
cdebug_log(149,0) << "optimal:[" << DbU::getValueString(optimalMin) cdebug_log(149,0) << "optimal:[" << DbU::getValueString(optimalMin)
<< " " << DbU::getValueString(optimalMin) << "]" << endl; << " " << DbU::getValueString(optimalMax) << "]" << endl;
if (getAxis() < optimalMin) { if (getAxis() < optimalMin) {
setAxis( optimalMin, flags ); setAxis( optimalMin, flags );
@ -973,30 +973,30 @@ namespace Anabatic {
if (perpandMin < minGCell) attractors.addAttractor( minGCell ); if (perpandMin < minGCell) attractors.addAttractor( minGCell );
if (perpandMax > maxGCell) attractors.addAttractor( maxGCell ); if (perpandMax > maxGCell) attractors.addAttractor( maxGCell );
} else if (autoSegment->isLongLocal()) {
cdebug_log(145,0) << "| Used as long global attractor." << endl;
DbU::Unit perpandMin = autoSegment->getSourceU();
DbU::Unit perpandMax = autoSegment->getTargetU();
if (perpandMin != perpandMax) {
if (perpandMin == getAxis()) attractors.addAttractor( perpandMax );
if (perpandMax == getAxis()) attractors.addAttractor( perpandMin );
}
} else if (autoSegment->isLocal()) { } else if (autoSegment->isLocal()) {
if (not autoSegment->isStrongTerminal()) { cdebug_tabw(145,-1); continue; } if (autoSegment->isStrongTerminal()) {
DbU::Unit terminalMin;
DbU::Unit terminalMax;
DbU::Unit terminalMin; if (getTerminalInterval( *autoSegment
DbU::Unit terminalMax; , NULL
, isHorizontal()
if (getTerminalInterval( *autoSegment , terminalMin
, NULL , terminalMax )) {
, isHorizontal() attractors.addAttractor( terminalMin );
, terminalMin if (terminalMin != terminalMax)
, terminalMax )) { attractors.addAttractor( terminalMax );
attractors.addAttractor( terminalMin ); }
if (terminalMin != terminalMax) } else if (autoSegment->isLongLocal()) {
attractors.addAttractor( terminalMax ); cdebug_log(145,0) << "| Used as long global attractor." << endl;
DbU::Unit perpandMin = autoSegment->getSourceU();
DbU::Unit perpandMax = autoSegment->getTargetU();
if (perpandMin != perpandMax) {
if (perpandMin == getAxis()) attractors.addAttractor( perpandMax );
if (perpandMax == getAxis()) attractors.addAttractor( perpandMin );
}
} }
} }
cdebug_tabw(145,-1); cdebug_tabw(145,-1);

View File

@ -323,7 +323,12 @@ namespace Hurricane {
case Kilo: unitPower = 'k'; break; case Kilo: unitPower = 'k'; break;
default: unitPower = '?'; break; default: unitPower = '?'; break;
} }
os << setprecision(3) << toPhysical(u,_stringModeUnitPower); switch ( u ) {
case Min: os << "MIN:"; break;
case Max: os << "MAX:"; break;
default:
os << setprecision(3) << toPhysical(u,_stringModeUnitPower);
}
} else { } else {
if (_stringMode != Db) if (_stringMode != Db)
cerr << "[ERROR] Unknown Unit representation mode: " << _stringMode << endl; cerr << "[ERROR] Unknown Unit representation mode: " << _stringMode << endl;

View File

@ -79,7 +79,7 @@ namespace Katana {
void DataNegociate::update () void DataNegociate::update ()
{ {
DebugSession::open( _trackSegment->getNet(), 150, 160 ); DebugSession::open( _trackSegment->getNet(), 156, 160 );
//cdebug_log(9000,0) << "Deter| DataNegociate::update() - " << _trackSegment << endl; //cdebug_log(9000,0) << "Deter| DataNegociate::update() - " << _trackSegment << endl;
cdebug_log(159,1) << "DataNegociate::update() - " << _trackSegment << endl; cdebug_log(159,1) << "DataNegociate::update() - " << _trackSegment << endl;

View File

@ -15,6 +15,7 @@
#include "anabatic/AutoSegment.h" #include "anabatic/AutoSegment.h"
#include "katana/DataSymmetric.h" #include "katana/DataSymmetric.h"
#include "katana/Session.h"
namespace { namespace {
@ -124,6 +125,10 @@ namespace Katana {
const unsigned int mask = ~(AutoSegmentFlag::SegIsReduced); const unsigned int mask = ~(AutoSegmentFlag::SegIsReduced);
Message errors ( 0, "[ERROR]" ); Message errors ( 0, "[ERROR]" );
// Temporary hardwired: M2 (depth 1) for H pitch, M3 (depth 2) for V pitch.
DbU::Unit hPitch = Session::getPitch( 1 );
DbU::Unit vPitch = Session::getPitch( 2 );
size_t refs = 0; size_t refs = 0;
size_t syms = 0; size_t syms = 0;
for ( const array<AutoSegment*,2>& paired : _paireds ) { for ( const array<AutoSegment*,2>& paired : _paireds ) {
@ -162,7 +167,7 @@ namespace Katana {
_valid = false; _valid = false;
} }
if (2*getSymAxis() - paired[0]->getAxis() != paired[1]->getAxis()) { if (std::abs( 2*getSymAxis() - paired[0]->getAxis() - paired[1]->getAxis() ) > 2*vPitch ) {
errors.newline() << "Mirror axis mismatch @ [" << index << "] " errors.newline() << "Mirror axis mismatch @ [" << index << "] "
<< DbU::getValueString(paired[1]->getAxis()) << " (should be: " << DbU::getValueString(paired[1]->getAxis()) << " (should be: "
<< DbU::getValueString(2*getSymAxis() - paired[0]->getAxis()) << ")"; << DbU::getValueString(2*getSymAxis() - paired[0]->getAxis()) << ")";
@ -179,7 +184,7 @@ namespace Katana {
_valid = false; _valid = false;
} }
if (paired[0]->getAxis() != paired[1]->getAxis()) { if ( std::abs( paired[0]->getAxis() - paired[1]->getAxis() ) > 2*hPitch ) {
errors.newline() << "Axis mismatch index " << index << " " errors.newline() << "Axis mismatch index " << index << " "
<< DbU::getValueString(paired[1]->getAxis()) << " (should be:" << DbU::getValueString(paired[1]->getAxis()) << " (should be:"
<< DbU::getValueString(paired[0]->getAxis()) << ")"; << DbU::getValueString(paired[0]->getAxis()) << ")";
@ -190,7 +195,7 @@ namespace Katana {
} }
} else { } else {
if (paired[0]->isHorizontal()) { if (paired[0]->isHorizontal()) {
if (2*getSymAxis() - paired[0]->getAxis() != paired[1]->getAxis()) { if ( std::abs( 2*getSymAxis() - paired[0]->getAxis() - paired[1]->getAxis() ) > 2*hPitch ) {
errors.newline() << "Mirror axis mismatch index " << index << " " errors.newline() << "Mirror axis mismatch index " << index << " "
<< DbU::getValueString(paired[1]->getAxis()) << " (should be:" << DbU::getValueString(paired[1]->getAxis()) << " (should be:"
<< DbU::getValueString(2*getSymAxis() - paired[0]->getAxis()) << ")"; << DbU::getValueString(2*getSymAxis() - paired[0]->getAxis()) << ")";
@ -199,7 +204,7 @@ namespace Katana {
_valid = false; _valid = false;
} }
} else { } else {
if (paired[0]->getAxis() != paired[1]->getAxis()) { if ( std::abs( paired[0]->getAxis() != paired[1]->getAxis() ) > 2*vPitch ) {
errors.newline() << "Axis mismatch index " << index << " " errors.newline() << "Axis mismatch index " << index << " "
<< DbU::getValueString(paired[1]->getAxis()) << " (should be:" << DbU::getValueString(paired[1]->getAxis()) << " (should be:"
<< DbU::getValueString(paired[0]->getAxis()) << ")"; << DbU::getValueString(paired[0]->getAxis()) << ")";
@ -217,10 +222,10 @@ namespace Katana {
errors.newline(); errors.newline();
if (errors.size()) { if (errors.size()) {
cmess2 << " pairing failed." << endl; //cmess2 << " pairing failed." << endl;
errors.print( cmess2 ); errors.print( cmess2 );
} else { } else {
cmess2 << " paired." << endl; //cmess2 << " paired." << endl;
} }
return _valid; return _valid;

View File

@ -275,9 +275,10 @@ namespace Katana {
KatanaEngine* katana = getForFramework( NoFlags ); KatanaEngine* katana = getForFramework( NoFlags );
if (katana) { if (katana) {
katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet ); katana->loadGlobalRouting( Anabatic::EngineLoadGrByNet );
katana->runTest(); // Now done through Horus.
//katana->runTest();
katana->runNegociate( Flags::SymmetricStage ); katana->runNegociate( Flags::SymmetricStage );
katana->runNegociate(); //katana->runNegociate();
} }
} }

View File

@ -95,7 +95,7 @@ namespace Katana {
if (not _segment) if (not _segment)
throw Error( "Manipulator::Manipulator(): cannot build upon a NULL TrackElement." ); throw Error( "Manipulator::Manipulator(): cannot build upon a NULL TrackElement." );
DebugSession::open( _segment->getNet(), 149, 160 ); DebugSession::open( _segment->getNet(), 156, 160 );
_data = _segment->getDataNegociate(); _data = _segment->getDataNegociate();
if (_data) _event = _data->getRoutingEvent(); if (_data) _event = _data->getRoutingEvent();
@ -635,7 +635,8 @@ namespace Katana {
bool rightIntrication = false; bool rightIntrication = false;
bool success = true; bool success = true;
cdebug_log(159,0) << "Manipulator::insertInTrack() - " << toFree << endl; cdebug_log(159,1) << "Manipulator::insertInTrack(size_t) - " << toFree << endl;
cdebug_log(159,0) << _segment << endl;
for ( size_t i = begin ; success && (i < end) ; i++ ) { for ( size_t i = begin ; success && (i < end) ; i++ ) {
TrackElement* segment2 = track->getSegment(i); TrackElement* segment2 = track->getSegment(i);
@ -748,6 +749,10 @@ namespace Katana {
} }
} }
if ( shrinkLeft ) { if ( shrinkLeft ) {
cdebug_log(159,0) << "Move PP to right: "
<< DbU::getValueString(toFree.getVMax()) << " + "
<< DbU::getValueString(getPPitch()/2)
<< endl;
if ( not (success=Manipulator(segment3,_fsm) if ( not (success=Manipulator(segment3,_fsm)
.ripup( SegmentAction::OtherRipupPerpandAndPushAside .ripup( SegmentAction::OtherRipupPerpandAndPushAside
, toFree.getVMax() + getPPitch()/2 , toFree.getVMax() + getPPitch()/2
@ -763,8 +768,7 @@ namespace Katana {
} }
} else { } else {
if ( not (success=Manipulator(segment3,_fsm).ripup( SegmentAction::OtherRipup if ( not (success=Manipulator(segment3,_fsm).ripup( SegmentAction::OtherRipup
| SegmentAction::EventLevel3 | SegmentAction::EventLevel3 )) )
)) )
break; break;
} }
} }
@ -774,10 +778,10 @@ namespace Katana {
if ( success ) { if ( success ) {
cdebug_log(159,0) << "Manipulator::insertInTrack() success" << endl; cdebug_log(159,0) << "Manipulator::insertInTrack() success" << endl;
_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.getCost(itrack).getTrack()->getAxis() );
unsigned int flags = 0; unsigned int flags = 0;
if ( rightIntrication ) flags |= RightAxisHint; if ( rightIntrication ) flags |= RightAxisHint;
@ -787,6 +791,7 @@ namespace Katana {
} else } else
_fsm.clearActions (); _fsm.clearActions ();
cdebug_tabw(159,-1);
return success; return success;
} }
@ -802,7 +807,7 @@ namespace Katana {
set<TrackElement*> canonicals; set<TrackElement*> canonicals;
bool success = true; bool success = true;
cdebug_log(159,0) << "Manipulator::forceToTrack() - " << toFree << endl; cdebug_log(159,1) << "Manipulator::forceToTrack(size_t) - " << toFree << endl;
for ( size_t i=begin ; success and (i < end) ; ++i ) { for ( size_t i=begin ; success and (i < end) ; ++i ) {
TrackElement* segment2 = track->getSegment(i); TrackElement* segment2 = track->getSegment(i);
@ -829,7 +834,7 @@ namespace Katana {
canonicals.clear(); canonicals.clear();
for( TrackElement* segment3 for( TrackElement* segment3
: segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { : segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) {
DataNegociate* data3 = segment3->getDataNegociate(); DataNegociate* data3 = segment3->getDataNegociate();
if (not data3) continue; if (not data3) continue;
@ -848,6 +853,7 @@ namespace Katana {
, _fsm.getCost(itrack).getTrack()->getAxis() ); , _fsm.getCost(itrack).getTrack()->getAxis() );
} }
cdebug_tabw(159,-1);
return success; return success;
} }
@ -926,15 +932,15 @@ namespace Katana {
{ {
cdebug_log(159,1) << "Manipulator::forceOverLocals()" << endl; cdebug_log(159,1) << "Manipulator::forceOverLocals()" << endl;
vector<TrackCost>& costs = _fsm.getCosts(); vector< array<TrackCost,2> >& 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].isFixed() if ( costs[itrack][0].isFixed()
or costs[itrack].isBlockage() or costs[itrack][0].isBlockage()
or costs[itrack].isInfinite() or costs[itrack][0].isInfinite()
or costs[itrack].isOverlapGlobal() ) or costs[itrack][0].isOverlapGlobal() )
continue; continue;
bool success = true; bool success = true;

View File

@ -311,24 +311,21 @@ namespace Katana {
RoutingEvent* fork = NULL; RoutingEvent* fork = NULL;
if ( (getStage() != Repair) and isUnimplemented() ) { if ( (getStage() != Repair) and isUnimplemented() ) {
cdebug_log(159,0) << "Reschedule: cancelled (Unimplemented) " cdebug_log(159,0) << "Reschedule: cancelled (Unimplemented) -> " << fork << endl;
<< " -> " << fork << endl;
return NULL; return NULL;
} }
if (not isProcessed()) { if (not isProcessed()) {
fork = this; fork = this;
cdebug_log(159,0) << "Reschedule/Self: " cdebug_log(159,0) << "Reschedule/Self: -> "
<< " -> " << eventLevel << ":" << fork << endl;
<< eventLevel << ":" << fork << endl;
} else { } else {
fork = clone(); fork = clone();
fork->_processed = false; fork->_processed = false;
_segment->getDataNegociate()->setRoutingEvent( fork ); _segment->getDataNegociate()->setRoutingEvent( fork );
cdebug_log(159,0) << "Reschedule/Fork: " cdebug_log(159,0) << "Reschedule/Fork: -> " << fork << endl;
<< " -> " << fork << endl;
} }
if (fork->_eventLevel < eventLevel) if (fork->_eventLevel < eventLevel)
@ -393,7 +390,7 @@ namespace Katana {
#endif #endif
} }
DebugSession::open( _segment->getNet(), 149, 160 ); DebugSession::open( _segment->getNet(), 156, 160 );
cdebug_log(9000,0) << "Deter| Event " cdebug_log(9000,0) << "Deter| Event "
<< getProcesseds() << getProcesseds()
@ -418,6 +415,9 @@ namespace Katana {
if ( isProcessed() or isDisabled() ) { if ( isProcessed() or isDisabled() ) {
cdebug_log(159,0) << "Already processed or disabled." << endl; cdebug_log(159,0) << "Already processed or disabled." << endl;
} else { } else {
if (_segment->hasSymmetric()) {
}
setProcessed(); setProcessed();
setTimeStamp( _processeds ); setTimeStamp( _processeds );
@ -460,7 +460,7 @@ namespace Katana {
cdebug_tabw(159,1); cdebug_tabw(159,1);
fsm.getData()->incRipupCount(); fsm.incRipupCount();
cdebug_log(159,0) << "| Candidate Tracks:" << endl; cdebug_log(159,0) << "| Candidate Tracks:" << endl;
size_t itrack = 0; size_t itrack = 0;
@ -468,22 +468,16 @@ namespace Katana {
cdebug_log(159,0) << "| " << itrack << ":" << fsm.getCost(itrack) << endl; cdebug_log(159,0) << "| " << itrack << ":" << fsm.getCost(itrack) << endl;
itrack = 0; itrack = 0;
if ( (not isOverConstrained()) and Manipulator(_segment,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;
resetInsertState(); fsm.bindToTrack( itrack );
_axisHistory = _segment->getAxis();
_eventLevel = 0;
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << fsm.getCost(itrack).getTrack() << endl;
Session::addInsertEvent( _segment, fsm.getCost(itrack).getTrack() );
fsm.setState( SegmentFsm::SelfInserted );
} else { } else {
// Do ripup. // Do ripup.
if (fsm.getState() == SegmentFsm::EmptyTrackList) { if (fsm.getState() == SegmentFsm::EmptyTrackList) {
Manipulator(_segment,fsm).ripupPerpandiculars(); fsm.ripupPerpandiculars();
} else { } else {
if (Manipulator(_segment,fsm).canRipup(Manipulator::NotOnLastRipup)) { if (fsm.canRipup(Manipulator::NotOnLastRipup)) {
if (cdebug.enabled(9000)) { if (cdebug.enabled(9000)) {
for ( itrack=0 ; itrack<fsm.getCosts().size() ; itrack++ ) { for ( itrack=0 ; itrack<fsm.getCosts().size() ; itrack++ ) {
cdebug_log(9000,0) << "Deter| | Candidate Track: " << fsm.getCost(itrack) << endl; cdebug_log(9000,0) << "Deter| | Candidate Track: " << fsm.getCost(itrack) << endl;
@ -506,7 +500,7 @@ namespace Katana {
// Ripup limit has been reached. // Ripup limit has been reached.
if (isOverConstrained()) { if (isOverConstrained()) {
cdebug_log(159,0) << "Immediate slackening due to overconstraint" << endl; cdebug_log(159,0) << "Immediate slackening due to overconstraint" << endl;
fsm.getData()->setState( DataNegociate::Slacken ); fsm.setDataState( DataNegociate::Slacken );
} }
if (not fsm.slackenTopology()) { if (not fsm.slackenTopology()) {
fsm.setState( SegmentFsm::SelfMaximumSlack ); fsm.setState( SegmentFsm::SelfMaximumSlack );
@ -545,8 +539,7 @@ namespace Katana {
and (fsm.getCost(0).getTrack() != _segment->getTrack()) ) { and (fsm.getCost(0).getTrack() != _segment->getTrack()) ) {
cerr << "_processPack(): move to " << fsm.getCost(0).getTrack() << endl; cerr << "_processPack(): move to " << fsm.getCost(0).getTrack() << endl;
Session::addMoveEvent( _segment, fsm.getCost(0).getTrack() ); fsm.moveToTrack( 0 );
fsm.setState( SegmentFsm::SelfInserted );
} }
} }
@ -563,6 +556,7 @@ namespace Katana {
SegmentFsm fsm ( this, queue, history ); SegmentFsm fsm ( this, queue, history );
if (fsm.getState() == SegmentFsm::MissingData ) return; if (fsm.getState() == SegmentFsm::MissingData ) return;
if (fsm.getState() == SegmentFsm::EmptyTrackList) return; if (fsm.getState() == SegmentFsm::EmptyTrackList) return;
if (fsm.isSymmetric()) return;
cdebug_tabw(159,1); cdebug_tabw(159,1);
for ( size_t i = 0 ; i < fsm.getCosts().size() ; i++ ) for ( size_t i = 0 ; i < fsm.getCosts().size() ; i++ )
@ -571,8 +565,7 @@ namespace Katana {
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;
Session::addInsertEvent( _segment, fsm.getCost(0).getTrack() ); fsm.bindToTrack( 0 );
fsm.setState( SegmentFsm::SelfInserted );
} else { } else {
switch ( fsm.getData()->getStateCount() ) { switch ( fsm.getData()->getStateCount() ) {
case 1: case 1:
@ -599,7 +592,7 @@ namespace Katana {
void RoutingEvent::revalidate () void RoutingEvent::revalidate ()
{ {
DebugSession::open( _segment->getNet(), 150, 160 ); DebugSession::open( _segment->getNet(), 156, 160 );
cdebug_log(159,1) << "RoutingEvent::revalidate() - " << this << endl; cdebug_log(159,1) << "RoutingEvent::revalidate() - " << this << endl;

View File

@ -36,6 +36,26 @@ namespace {
using namespace Katana; using namespace Katana;
// -------------------------------------------------------------------
// Class : "CompareCostArray".
class CompareCostArray {
public:
inline CompareCostArray ( unsigned int flags=0 );
inline bool operator() ( const array<TrackCost,2>& lhs, const array<TrackCost,2>& rhs );
private:
TrackCost::Compare _compare;
};
inline CompareCostArray::CompareCostArray ( unsigned int 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".
@ -363,7 +383,7 @@ namespace Katana {
// "_immediate" ripup flags was associated with "perpandicular", as they // "_immediate" ripup flags was associated with "perpandicular", as they
// must be re-inserted *before* any parallel. Must look to solve the redundancy. // must be re-inserted *before* any parallel. Must look to solve the redundancy.
DebugSession::open( _segment->getNet(), 150, 160 ); DebugSession::open( _segment->getNet(), 156, 160 );
if (_type & Perpandicular) { if (_type & Perpandicular) {
cdebug_log(159,0) << "* Riping Pp " << _segment << endl; cdebug_log(159,0) << "* Riping Pp " << _segment << endl;
@ -438,43 +458,85 @@ namespace Katana {
// Class : "SegmentFsm". // Class : "SegmentFsm".
SegmentFsm::SegmentFsm ( RoutingEvent* event, RoutingEventQueue& queue, RoutingEventHistory& history ) SegmentFsm::SegmentFsm ( RoutingEvent* event1
: _event (event) , RoutingEventQueue& queue
, RoutingEventHistory& history )
: _event1 (event1)
, _event2 (NULL)
, _queue (queue) , _queue (queue)
, _history (history) , _history (history)
, _state (0) , _state (0)
, _data (NULL) , _data1 (NULL)
, _data2 (NULL)
, _constraint () , _constraint ()
, _optimal () , _optimal ()
, _costs () , _costs ()
, _actions () , _actions ()
, _fullBlocked(true) , _fullBlocked(true)
, _sameAxis (false)
, _useEvent2 (false)
{ {
TrackElement* segment = _event->getSegment(); DataSymmetric* symData = NULL;
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer()); TrackElement* segment1 = _event1->getSegment();
_event->setTracksFree( 0 ); TrackElement* segment2 = segment1->getSymmetric();
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment1->getLayer());
_event1->setTracksFree( 0 );
_data = segment->getDataNegociate(); _data1 = segment1->getDataNegociate();
if (not _data) { if (not _data1) {
_state = MissingData; _state = MissingData;
return; return;
} }
_data->update(); _data1->update();
_event->revalidate(); _event1->revalidate();
_constraint = _event->getConstraints(); if (segment2) {
_optimal = _event->getOptimal(); symData = Session::getKatanaEngine()->getDataSymmetric( segment1->getNet() );
const Interval& perpandicular = _event->getPerpandicularFree(); _data2 = segment2->getDataNegociate();
if (not _data2 or not symData) {
_state = MissingData;
return;
}
_event2 = _data2->getRoutingEvent();
_event2->setTracksFree( 0 );
_data2->update();
_event2->revalidate();
_sameAxis = (segment1->isVertical() xor symData->isSymVertical());
}
Interval perpandicular = _event1->getPerpandicularFree();
cdebug_log(159,0) << "* Perpandicular (master): " << perpandicular << endl;
_constraint = _event1->getConstraints();
_optimal = _event1->getOptimal();
if (_event2) {
if (_sameAxis) {
_constraint .intersection( _event2->getConstraints() );
perpandicular.intersection( _event2->getPerpandicularFree() );
cdebug_log(159,0) << "* Perpandicular (slave): same axis "
<< _event2->getPerpandicularFree() << endl;
} else {
_constraint .intersection( symData->getSymmetrical( _event2->getConstraints() ) );
perpandicular.intersection( symData->getSymmetrical( _event2->getPerpandicularFree() ) );
cdebug_log(159,0) << "* Perpandicular (slave): PP axis "
<< symData->getSymmetrical(_event2->getPerpandicularFree()) << endl;
}
}
cdebug_log(159,0) << "Anabatic intervals:" << endl; cdebug_log(159,0) << "Anabatic intervals:" << endl;
cdebug_log(159,0) << "* Optimal: " << _optimal << endl; cdebug_log(159,0) << "* Optimal: " << _optimal << endl;
cdebug_log(159,0) << "* Constraints: " << _constraint << endl; cdebug_log(159,0) << "* Constraints: " << _constraint << endl;
cdebug_log(159,0) << "* Perpandicular: " << perpandicular << endl; cdebug_log(159,0) << "* Perpandicular: " << perpandicular << endl;
cdebug_log(159,0) << "* AxisHint: " << DbU::getValueString(_event->getAxisHint()) << endl; cdebug_log(159,0) << "* AxisHint: " << DbU::getValueString(_event1->getAxisHint()) << endl;
if (_event->getTracksNb()) { if (_event1->getTracksNb()) {
if (_constraint.getIntersection(perpandicular).isEmpty()) { if (_constraint.getIntersection(perpandicular).isEmpty()) {
cdebug_log(159,0) << "Perpandicular free is too tight." << endl; cdebug_log(159,0) << "Perpandicular free is too tight." << endl;
_state = EmptyTrackList; _state = EmptyTrackList;
@ -487,46 +549,64 @@ namespace Katana {
if (_state == EmptyTrackList) return; if (_state == EmptyTrackList) return;
cdebug_log(159,0) << "Negociate intervals:" << endl; cdebug_log(159,0) << "Negociate intervals:" << endl;
cdebug_log(159,0) << "* Optimal: " << _optimal << endl; cdebug_log(159,0) << "* Optimal: " << _optimal << endl;
cdebug_log(159,1) << "* Constraints: " << _constraint << endl; cdebug_log(159,0) << "* Constraints: " << _constraint << endl;
cdebug_log(159,1) << "* _sameAxis: " << _sameAxis << endl;
// 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 inLocalDepth = (depth < 3);
bool isOneLocalTrack = (segment->isLocal()) bool isOneLocalTrack = (segment1->isLocal())
and (segment->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0); and (segment1->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0);
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment->getLayer()); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment1->getLayer());
for ( Track* track : Tracks_Range::get(plane,_constraint) ) { for ( Track* track1 : Tracks_Range::get(plane,_constraint) ) {
unsigned int costflags = 0; unsigned int costflags = 0;
costflags |= (segment->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0; costflags |= (segment1->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0;
if (not segment->isReduced()) Track* track2 = NULL;
_costs.push_back( track->getOverlapCost(segment,costflags) ); if (_event2) {
else track2 =
_costs.push_back( TrackCost(track,segment->getNet()) ); (_sameAxis) ? track1 : plane->getTrackByPosition( symData->getSymmetrical( track1->getAxis() ) );
_costs.back().setAxisWeight ( _event->getAxisWeight(track->getAxis()) );
_costs.back().incDeltaPerpand( _data->getWiringDelta(track->getAxis()) );
if (segment->isGlobal()) {
cdebug_log(9000,0) << "Deter| setForGlobal() on " << track << endl;
_costs.back().setForGlobal();
} }
if ( inLocalDepth and (_costs.back().getDataState() == DataNegociate::MaximumSlack) ) _costs.push_back( array<TrackCost,2>( { TrackCost(NULL), TrackCost(NULL) } ) );
_costs.back().setInfinite(); 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()) );
_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 if ( isOneLocalTrack
and _costs.back().isOverlapGlobal() and _costs.back()[0].isOverlapGlobal()
and (_costs.back().getDataState() >= DataNegociate::ConflictSolveByHistory) ) and (_costs.back()[0].getDataState() >= DataNegociate::ConflictSolveByHistory) )
_costs.back().setInfinite(); _costs.back()[0].setInfinite();
_costs.back().consolidate(); _costs.back()[0].consolidate();
if ( _fullBlocked and (not _costs.back().isBlockage() and not _costs.back().isFixed()) ) if ( _fullBlocked and (not _costs.back()[0].isBlockage() and not _costs.back()[0].isFixed()) )
_fullBlocked = false; _fullBlocked = false;
cdebug_log(159,0) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << track << endl; cdebug_log(155,0) << "| " << _costs.back()[0] << ((_fullBlocked)?" FB ": " -- ") << track1 << endl;
} }
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
@ -540,7 +620,7 @@ namespace Katana {
// << _constraint << " " << "." << endl; // << _constraint << " " << "." << endl;
} else { } else {
cerr << Bug( " %s Track_Range() failed to find Tracks in %s (they exists)." cerr << Bug( " %s Track_Range() failed to find Tracks in %s (they exists)."
, getString(segment).c_str() , getString(segment1).c_str()
, getString(_constraint).c_str() , getString(_constraint).c_str()
) << endl; ) << endl;
} }
@ -548,10 +628,10 @@ namespace Katana {
} }
unsigned int flags = 0; unsigned int flags = 0;
flags |= (segment->isStrap()) ? TrackCost::IgnoreAxisWeight : 0; flags |= (segment1->isStrap()) ? TrackCost::IgnoreAxisWeight : 0;
flags |= (segment->isLocal() flags |= (segment1->isLocal()
and (_data->getState() < DataNegociate::Minimize) and (_data1->getState() < DataNegociate::Minimize)
and (_data->getRipupCount() < 5)) and (_data1->getRipupCount() < 5))
? TrackCost::DiscardGlobals : 0; ? TrackCost::DiscardGlobals : 0;
flags |= (RoutingEvent::getStage() == RoutingEvent::Repair) ? TrackCost::IgnoreSharedLength : 0; flags |= (RoutingEvent::getStage() == RoutingEvent::Repair) ? TrackCost::IgnoreSharedLength : 0;
@ -559,11 +639,23 @@ namespace Katana {
cdebug_log(159,0) << "TrackCost::Compare() - DiscardGlobals" << endl; cdebug_log(159,0) << "TrackCost::Compare() - DiscardGlobals" << endl;
} }
sort( _costs.begin(), _costs.end(), TrackCost::Compare(flags) ); sort( _costs.begin(), _costs.end(), CompareCostArray(flags) );
size_t i=0; size_t i=0;
for ( ; (i<_costs.size()) and _costs[i].isFree() ; i++ ); for ( ; (i<_costs.size()) and _costs[i][0].isFree() ; i++ );
_event->setTracksFree ( i ); _event1->setTracksFree ( i );
if (_event2) {
for ( ; (i<_costs.size()) and _costs[i][1].isFree() ; i++ );
_event2->setTracksFree ( i );
}
}
void SegmentFsm::setDataState ( unsigned int state )
{
_data1->setState( state );
if (_data2) _data2->setState( state );
} }
@ -581,7 +673,7 @@ namespace Katana {
void SegmentFsm::doActions () void SegmentFsm::doActions ()
{ {
cdebug_log(159,0) << "SegmentFsm::doActions() - " << _actions.size() << endl; cdebug_log(159,1) << "SegmentFsm::doActions() - " << _actions.size() << endl;
bool ripupOthersParallel = false; bool ripupOthersParallel = false;
bool ripedByLocal = getEvent()->getSegment()->isLocal(); bool ripedByLocal = getEvent()->getSegment()->isLocal();
@ -597,7 +689,7 @@ namespace Katana {
if ( (_actions[i].getType() & SegmentAction::SelfInsert) and ripupOthersParallel ) if ( (_actions[i].getType() & SegmentAction::SelfInsert) and ripupOthersParallel )
_actions[i].setFlag ( SegmentAction::EventLevel3 ); _actions[i].setFlag ( SegmentAction::EventLevel3 );
DebugSession::open ( _actions[i].getSegment()->getNet(), 150, 160 ); DebugSession::open ( _actions[i].getSegment()->getNet(), 156, 160 );
if ( not _actions[i].doAction(_queue) ) { if ( not _actions[i].doAction(_queue) ) {
cinfo << "[INFO] Failed action on " << _actions[i].getSegment() << endl; cinfo << "[INFO] Failed action on " << _actions[i].getSegment() << endl;
} }
@ -605,36 +697,113 @@ namespace Katana {
} }
_actions.clear (); _actions.clear ();
cdebug_tabw(159,-1);
}
void SegmentFsm::incRipupCount ()
{
_data1->incRipupCount();
if (_data2) _data2->incRipupCount();
} }
bool SegmentFsm::insertInTrack ( size_t i ) bool SegmentFsm::insertInTrack ( size_t i )
{ {
cdebug_log(159,0) << "SegmentFsm::insertInTrack() istate:" << _event->getInsertState() cdebug_log(159,0) << "SegmentFsm::insertInTrack() istate:" << _event1->getInsertState()
<< " track:" << i << endl; << " track:" << i << endl;
_event->incInsertState(); bool success = true;
switch ( _event->getInsertState() ) {
_event1->incInsertState();
switch ( _event1->getInsertState() ) {
case 1: case 1:
if ( Manipulator(_event->getSegment(),*this).insertInTrack(i) ) return true; success = Manipulator(_event1->getSegment(),useEvent1()).insertInTrack(i);
_event->incInsertState(); success = success and (not _event2 or Manipulator(_event2->getSegment(),useEvent2()).insertInTrack(i));
if (success) break;
_event1->incInsertState();
clearActions();
case 2: case 2:
if ( Manipulator(_event->getSegment(),*this).shrinkToTrack(i) ) return true; success = Manipulator(_event1->getSegment(),useEvent1()).shrinkToTrack(i);
_event->incInsertState(); success = success and (not _event2 or Manipulator(_event2->getSegment(),useEvent2()).shrinkToTrack(i));
if (success) break;
_event1->incInsertState();
clearActions();
case 3: case 3:
if ( Manipulator(_event->getSegment(),*this).forceToTrack(i) ) return true; success = Manipulator(_event1->getSegment(),useEvent1()).forceToTrack(i);
_event->incInsertState(); success = success and (not _event2 or Manipulator(_event2->getSegment(),useEvent2()).forceToTrack(i));
if (success) break;
_event1->incInsertState();
clearActions();
} }
return false;
useEvent1();
if (_event2) _event2->setInsertState( _event1->getInsertState() );
return success;
} }
void SegmentFsm::bindToTrack ( size_t i )
{
cdebug_log(159,0) << "SegmentFsm::bindToTrack() :" << " track:" << i << endl;
_event1->resetInsertState();
_event1->updateAxisHistory();
_event1->setEventLevel( 0 );
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl;
Session::addInsertEvent( getSegment1(), getCost1(i).getTrack() );
if (_event2) {
_event2->resetInsertState();
_event2->updateAxisHistory();
_event2->setEventLevel( 0 );
_event2->setProcessed( true );
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl;
Session::addInsertEvent( getSegment2(), getCost2(i).getTrack() );
}
setState( SegmentFsm::SelfInserted );
}
void SegmentFsm::moveToTrack ( size_t i )
{
cdebug_log(159,0) << "SegmentFsm::moveToTrack() :" << " track:" << i << endl;
Session::addMoveEvent( getSegment1(), getCost1(i).getTrack() );
if (_event2) {
cdebug_log(9000,0) << "Deter| addInsertEvent() @" << getCost1(i).getTrack() << endl;
Session::addMoveEvent( getSegment2(), getCost2(i).getTrack() );
}
setState( SegmentFsm::SelfInserted );
}
void SegmentFsm::ripupPerpandiculars ()
{
Manipulator(getSegment1(),*this).ripupPerpandiculars();
if (_event2)
Manipulator(getSegment2(),*this).ripupPerpandiculars();
}
bool SegmentFsm::canRipup ( unsigned int flags )
{
return Manipulator(getSegment1(),*this).canRipup(flags)
and (not _event2 or Manipulator(getSegment2(),*this).canRipup(flags));
}
bool SegmentFsm::conflictSolveByHistory () bool SegmentFsm::conflictSolveByHistory ()
{ {
bool success = false; bool success = false;
RipupHistory ripupHistory ( _event ); RipupHistory ripupHistory ( _event1 );
RoutingEvent* event; RoutingEvent* event;
TrackElement* segment = _event->getSegment(); TrackElement* segment = getEvent()->getSegment();
cdebug_log(159,0) << "SegmentFsm::conflictSolveByHistory()" << endl; cdebug_log(159,0) << "SegmentFsm::conflictSolveByHistory()" << endl;
@ -719,11 +888,11 @@ namespace Katana {
bool success = false; bool success = false;
Interval constraints; Interval constraints;
vector<Cs1Candidate> candidates; vector<Cs1Candidate> candidates;
TrackElement* segment = _event->getSegment(); TrackElement* segment = getEvent()->getSegment();
bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5,Flags::NoFlags) : segment->canMoveUp(1.0,Flags::CheckLowDensity); // MARK 1 bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5,Flags::NoFlags) : segment->canMoveUp(1.0,Flags::CheckLowDensity); // MARK 1
unsigned int relaxFlags = Manipulator::NoDoglegReuse unsigned int relaxFlags = Manipulator::NoDoglegReuse
| ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand | ((_data1 and (_data1->getStateCount() < 2)) ? Manipulator::AllowExpand
: Manipulator::NoExpand); : Manipulator::NoExpand);
cdebug_log(159,0) << "SegmentFsm::conflictSolveByPlaceds()" << endl; cdebug_log(159,0) << "SegmentFsm::conflictSolveByPlaceds()" << endl;
cdebug_log(159,0) << "| Candidates Tracks: " << endl; cdebug_log(159,0) << "| Candidates Tracks: " << endl;
@ -942,7 +1111,7 @@ namespace Katana {
size_t itrack = 0; size_t itrack = 0;
#if THIS_IS_DISABLED #if THIS_IS_DISABLED
TrackElement* segment = _event->getSegment(); TrackElement* segment = getEvent()->getSegment();
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;
@ -996,7 +1165,6 @@ namespace Katana {
} }
bool SegmentFsm::_slackenStrap ( TrackElement*& segment, DataNegociate*& data, unsigned int flags ) bool SegmentFsm::_slackenStrap ( TrackElement*& segment, DataNegociate*& data, unsigned int flags )
{ {
cdebug_log(159,0) << "Strap segment Fsm." << endl; cdebug_log(159,0) << "Strap segment Fsm." << endl;
@ -1216,30 +1384,40 @@ namespace Katana {
bool SegmentFsm::slackenTopology ( unsigned int flags ) bool SegmentFsm::slackenTopology ( unsigned int flags )
{ {
bool success = false; bool success = false;
TrackElement* segment = getEvent()->getSegment(); TrackElement* segment1 = getSegment1();
DataNegociate* data = segment->getDataNegociate ();
unsigned int actionFlags = SegmentAction::SelfInsert|SegmentAction::EventLevel5; unsigned int actionFlags = SegmentAction::SelfInsert|SegmentAction::EventLevel5;
DebugSession::open( segment->getNet(), 150, 160 ); DebugSession::open( segment1->getNet(), 156, 160 );
cdebug_log(159,1) << "Slacken Topology for " << segment->getNet() cdebug_log(159,1) << "Slacken Topology for " << segment1->getNet()
<< " " << segment << endl; << " " << segment1 << endl;
if (not segment or not data) { cdebug_tabw(159,-1); DebugSession::close(); return false; } if (_data2) {
cdebug_log(159,0) << "Symmetric segments are not allowed to slacken (yet)" << endl;
cdebug_tabw(159,-1);
DebugSession::close();
return false;
}
_event->resetInsertState(); if (not segment1 or not _data1) { cdebug_tabw(159,-1); DebugSession::close(); return false; }
data->resetRipupCount();
if (segment->isStrap()) { success = _slackenStrap ( segment, data, flags ); } _event1->resetInsertState();
else if (segment->isLocal()) { success = _slackenLocal ( segment, data, flags ); } _data1->resetRipupCount();
else { success = _slackenGlobal( segment, data, flags ); } if (_event2) {
_event2->resetInsertState();
_data2->resetRipupCount();
}
if (segment1->isStrap()) { success = _slackenStrap ( segment1, _data1, flags ); }
else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); }
else { success = _slackenGlobal( segment1, _data1, flags ); }
if (success) { if (success) {
actionFlags |= SegmentAction::ResetRipup; actionFlags |= SegmentAction::ResetRipup;
addAction( segment, actionFlags ); addAction( segment1, actionFlags );
} else { } else {
clearActions(); clearActions();
if (data->getState() == DataNegociate::Unimplemented) { if (_data1->getState() == DataNegociate::Unimplemented) {
cinfo << "[UNSOLVED] " << segment << " unable to slacken topology." << endl; cinfo << "[UNSOLVED] " << segment1 << " unable to slacken topology." << endl;
} }
} }

View File

@ -50,8 +50,9 @@ namespace {
using Anabatic::AutoContactTerminal; using Anabatic::AutoContactTerminal;
using Anabatic::AutoSegment; using Anabatic::AutoSegment;
using Anabatic::AutoSegmentFlag; using Anabatic::AutoSegmentFlag;
using Katana::KatanaEngine; using Katana::TrackElement;
using Katana::DataSymmetric; using Katana::DataSymmetric;
using Katana::KatanaEngine;
using Katana::Session; using Katana::Session;
@ -111,6 +112,7 @@ namespace {
void _doDualPairing (); void _doDualPairing ();
AutoContactTerminal* _getSymmetricTerminal ( AutoContactTerminal* masterContact ); AutoContactTerminal* _getSymmetricTerminal ( AutoContactTerminal* masterContact );
Component* _findMiddleComponent (); Component* _findMiddleComponent ();
void _associate ();
private: private:
KatanaEngine* _katana; KatanaEngine* _katana;
AutoSegment* _seed; AutoSegment* _seed;
@ -138,16 +140,21 @@ namespace {
DebugSession::open( _data->getNet(), 144, 146 ); DebugSession::open( _data->getNet(), 144, 146 );
// Temporary.
_data->setSymAxis( _katana->getCell()->getAbutmentBox().getCenter().getX() );
cmess2 << " - Net: \"" << _data->getNet()->getName() << "\" "; cmess2 << " - Net: \"" << _data->getNet()->getName() << "\" ";
cmess2 << "@" << DbU::getValueString(_data->getSymAxis()) << " "; cmess2 << "@" << DbU::getValueString(_data->getSymAxis()) << " ";
cmess2 << (_data->isSymVertical() ? "Vertical" : "Horizontal") << " "; cmess2 << (_data->isSymVertical() ? "Vertical" : "Horizontal") << " ";
if (_data->getSymNet()) cmess2 << "(paired: \"" << _data->getSymNet()->getName() << "\")"; if (_data->getSymNet()) cmess2 << "(paired: \"" << _data->getSymNet()->getName() << "\")";
else cmess2 << "(self symmetric)"; else cmess2 << "(self symmetric)";
cmess2 << endl;
if (_data->getSymNet()) _doDualPairing(); if (_data->getSymNet()) _doDualPairing();
else _doSelfPairing(); else _doSelfPairing();
if (_data->isValid()) _data->checkPairing(); if (_data->isValid()) _data->checkPairing();
_associate();
DebugSession::close(); DebugSession::close();
@ -201,9 +208,7 @@ namespace {
AutoContactTerminal* TopologicalPairing::_getSymmetricTerminal ( AutoContactTerminal* masterContact ) AutoContactTerminal* TopologicalPairing::_getSymmetricTerminal ( AutoContactTerminal* masterContact )
{ {
Point mirror = masterContact->getCenter(); Point mirror = _data->getSymmetrical( masterContact->getCenter() );
_data->getSymmetrical( mirror );
GCell* mirrorGCell = _katana->getGCellUnder( mirror ); GCell* mirrorGCell = _katana->getGCellUnder( mirror );
if (not mirrorGCell) { if (not mirrorGCell) {
cerr << Error( "getSymmetricTerminal() No GCell under symmetric position (%s,%s)." cerr << Error( "getSymmetricTerminal() No GCell under symmetric position (%s,%s)."
@ -221,7 +226,10 @@ namespace {
} }
} }
cerr << Error( "getSymmetricTerminal() Missing terminal contact in symmetric GCell." cerr << Error( "getSymmetricTerminal() Missing terminal contact in symmetric GCell.\n"
" master:%s\n"
" mirror:%s"
, getString(masterContact).c_str(), getString(mirrorGCell).c_str()
) << endl; ) << endl;
_data->setValid( false ); _data->setValid( false );
@ -352,6 +360,30 @@ namespace {
} }
void TopologicalPairing::_associate ()
{
cdebug_log(144,1) << "TopologicalPairing::_associate()" << endl;
//cmess1 << " - Associating symmetrics." << endl;
if (not _data->isValid()) return;
const DataSymmetric::Paireds& paireds = _data->getPaireds();
for ( auto sympair : paireds ) {
if (not sympair[0]->isCanonical() or not sympair[1]->isCanonical()) continue;
TrackElement* trackSegment0 = Session::lookup( sympair[0] );
TrackElement* trackSegment1 = Session::lookup( sympair[1] );
if (not trackSegment0 or not trackSegment1) continue;
trackSegment0->setSymmetric( trackSegment1 );
trackSegment1->setSymmetric( trackSegment0 );
}
cdebug_tabw(144,-1);
}
} // Anonymous namespace. } // Anonymous namespace.
@ -363,6 +395,7 @@ namespace Katana {
void KatanaEngine::runSymmetricRouter () void KatanaEngine::runSymmetricRouter ()
{ {
for ( Net* net : getCell()->getNets() ) { for ( Net* net : getCell()->getNets() ) {
if (not NetRoutingExtension::isSymmetric(net)) continue;
TopologicalPairing(this,net).doPairing(); TopologicalPairing(this,net).doPairing();
} }
} }

View File

@ -31,7 +31,7 @@ namespace Katana {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "TrackCost". // Class : "TrackCost".
TrackCost::TrackCost ( Track* track, Net* net ) TrackCost::TrackCost ( Track* track )
: _flags (ZeroCost) : _flags (ZeroCost)
, _track (track) , _track (track)
, _begin (Track::npos) , _begin (Track::npos)
@ -209,6 +209,19 @@ namespace Katana {
} }
void TrackCost::merge ( const TrackCost& other )
{
_terminals += other._terminals;
_delta += other._delta;
_deltaShared += other._deltaShared;
_deltaPerpand += other._deltaPerpand;
_axisWeight += other._axisWeight;
_distanceToFixed = std::min( _distanceToFixed, other._distanceToFixed );
_longuestOverlap = std::min( _longuestOverlap, other._longuestOverlap );
_dataState = std::max( _dataState, other._dataState );
}
string TrackCost::_getString () const string TrackCost::_getString () const
{ {
string s = "<" + _getTypeName(); string s = "<" + _getTypeName();

View File

@ -145,6 +145,7 @@ namespace Katana {
bool TrackElement::isUTurn () const { return false; } bool TrackElement::isUTurn () const { return false; }
bool TrackElement::isUserDefined () const { return false; } bool TrackElement::isUserDefined () const { return false; }
// Predicates. // Predicates.
bool TrackElement::hasSymmetric () const { return false; }
bool TrackElement::canSlacken () const { return false; } bool TrackElement::canSlacken () const { return false; }
bool TrackElement::canPivotUp ( float, unsigned int ) const { return false; }; bool TrackElement::canPivotUp ( float, unsigned int ) const { return false; };
bool TrackElement::canPivotDown ( float, unsigned int ) const { return false; }; bool TrackElement::canPivotDown ( float, unsigned int ) const { return false; };
@ -168,8 +169,10 @@ namespace Katana {
TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; } TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; }
TrackElement* TrackElement::getSourceDogleg () { return NULL; } TrackElement* TrackElement::getSourceDogleg () { return NULL; }
TrackElement* TrackElement::getTargetDogleg () { return NULL; } TrackElement* TrackElement::getTargetDogleg () { return NULL; }
TrackElement* TrackElement::getSymmetric () { return NULL; }
// Mutators. // Mutators.
void TrackElement::setTrack ( Track* track ) { _track = track; } void TrackElement::setTrack ( Track* track ) { _track = track; }
void TrackElement::setSymmetric ( TrackElement* ) { }
void TrackElement::updateFreedomDegree () { } void TrackElement::updateFreedomDegree () { }
void TrackElement::setDoglegLevel ( unsigned int ) { } void TrackElement::setDoglegLevel ( unsigned int ) { }
void TrackElement::swapTrack ( TrackElement* ) { } void TrackElement::swapTrack ( TrackElement* ) { }

View File

@ -61,6 +61,7 @@ namespace Katana {
TrackSegment::TrackSegment ( AutoSegment* segment, Track* track ) TrackSegment::TrackSegment ( AutoSegment* segment, Track* track )
: TrackElement (track) : TrackElement (track)
, _base (segment) , _base (segment)
, _symmetric (NULL)
, _freedomDegree(0) , _freedomDegree(0)
, _ppitch (0) , _ppitch (0)
, _data (NULL) , _data (NULL)
@ -161,6 +162,7 @@ namespace Katana {
bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); } bool TrackSegment::isUserDefined () const { return _base->isUserDefined(); }
bool TrackSegment::isUTurn () const { return _base->isUTurn(); } bool TrackSegment::isUTurn () const { return _base->isUTurn(); }
// Predicates. // Predicates.
bool TrackSegment::hasSymmetric () const { return _symmetric != NULL; }
// Accessors. // Accessors.
unsigned long TrackSegment::getId () const { return _base->getId(); } unsigned long TrackSegment::getId () const { return _base->getId(); }
Flags TrackSegment::getDirection () const { return _base->getDirection(); } Flags TrackSegment::getDirection () const { return _base->getDirection(); }
@ -174,6 +176,7 @@ namespace Katana {
Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); } Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); }
Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); } Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); }
TrackElement* TrackSegment::getCanonical ( Interval& i ) { return Session::lookup( _base->getCanonical(i)->base() ); } TrackElement* TrackSegment::getCanonical ( Interval& i ) { return Session::lookup( _base->getCanonical(i)->base() ); }
TrackElement* TrackSegment::getSymmetric () { return _symmetric; }
TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); } TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); }
// Mutators. // Mutators.
void TrackSegment::invalidate () { setFlags( TElemInvalidated ); _base->invalidate(); } void TrackSegment::invalidate () { setFlags( TElemInvalidated ); _base->invalidate(); }
@ -231,22 +234,22 @@ namespace Katana {
GCell* sourceGCell = base()->getAutoSource()->getGCell(); GCell* sourceGCell = base()->getAutoSource()->getGCell();
GCell* targetGCell = base()->getAutoTarget()->getGCell(); GCell* targetGCell = base()->getAutoTarget()->getGCell();
cdebug_log(159,0) << "getGCells(): sourceGCell: " << sourceGCell << endl; cdebug_log(155,0) << "getGCells(): sourceGCell: " << sourceGCell << endl;
cdebug_log(159,0) << "getGCells(): targetGCell: " << targetGCell << endl; cdebug_log(155,0) << "getGCells(): targetGCell: " << targetGCell << endl;
for ( AutoSegment* segment : base()->getAligneds() ) { for ( AutoSegment* segment : base()->getAligneds() ) {
cdebug_log(159,0) << "| " << segment << endl; cdebug_log(155,0) << "| " << segment << endl;
Anabatic::GCell* gcell = segment->getAutoSource()->getGCell(); Anabatic::GCell* gcell = segment->getAutoSource()->getGCell();
if (isLess(gcell,sourceGCell,direction)) { if (isLess(gcell,sourceGCell,direction)) {
sourceGCell = gcell; sourceGCell = gcell;
cdebug_log(159,0) << "getGCells(): new sourceGCell: " << sourceGCell << endl; cdebug_log(155,0) << "getGCells(): new sourceGCell: " << sourceGCell << endl;
} }
gcell = segment->getAutoTarget()->getGCell(); gcell = segment->getAutoTarget()->getGCell();
if (isGreater(gcell,targetGCell,direction)) { if (isGreater(gcell,targetGCell,direction)) {
targetGCell = gcell; targetGCell = gcell;
cdebug_log(159,0) << "getGCells(): new targetGCell: " << targetGCell << endl; cdebug_log(155,0) << "getGCells(): new targetGCell: " << targetGCell << endl;
} }
} }
@ -256,12 +259,12 @@ namespace Katana {
Flags side = (direction & Flags::Horizontal) ? Flags::EastSide : Flags::NorthSide; Flags side = (direction & Flags::Horizontal) ? Flags::EastSide : Flags::NorthSide;
DbU::Unit axis = getAxis(); DbU::Unit axis = getAxis();
cdebug_log(159,0) << "* dir:" << side._getString() << " @" << DbU::getValueString(axis) << endl; cdebug_log(155,0) << "* dir:" << side._getString() << " @" << DbU::getValueString(axis) << endl;
gcells.push_back( sourceGCell ); gcells.push_back( sourceGCell );
while ( sourceGCell != targetGCell ) { while ( sourceGCell != targetGCell ) {
sourceGCell = sourceGCell->getNeighborAt( direction, axis ); sourceGCell = sourceGCell->getNeighborAt( direction, axis );
cdebug_log(159,0) << "| " << sourceGCell << endl; cdebug_log(155,0) << "| " << sourceGCell << endl;
if (not sourceGCell) break; if (not sourceGCell) break;
gcells.push_back( sourceGCell ); gcells.push_back( sourceGCell );
@ -315,6 +318,10 @@ namespace Katana {
{ TrackElement::setTrack( track ); } { TrackElement::setTrack( track ); }
void TrackSegment::setSymmetric ( TrackElement* segment )
{ _symmetric = dynamic_cast<TrackSegment*>( segment ); }
void TrackSegment::detach () void TrackSegment::detach ()
{ {
cdebug_log(159,0) << "TrackSegment::detach() - <id:" << getId() << ">" << endl; cdebug_log(159,0) << "TrackSegment::detach() - <id:" << getId() << ">" << endl;
@ -880,7 +887,8 @@ namespace Katana {
Record* TrackSegment::_getRecord () const Record* TrackSegment::_getRecord () const
{ {
Record* record = TrackElement::_getRecord(); Record* record = TrackElement::_getRecord();
record->add( getSlot( "_base", _base ) ); record->add( getSlot( "_base" , _base ) );
record->add( getSlot( "_symmetric", _symmetric ) );
return record; return record;
} }

View File

@ -73,7 +73,7 @@ namespace Katana {
void TrackSegmentCost::update ( TrackElement* trackSegment ) void TrackSegmentCost::update ( TrackElement* trackSegment )
{ {
DebugSession::open ( trackSegment->getNet(), 150, 160 ); DebugSession::open ( trackSegment->getNet(), 156, 160 );
cdebug_log(159,1) << "TrackSegmentCost::update() - " << trackSegment << endl; cdebug_log(159,1) << "TrackSegmentCost::update() - " << trackSegment << endl;

View File

@ -38,15 +38,15 @@ namespace Katana {
: Hurricane::Locator<Track*>() : Hurricane::Locator<Track*>()
, _constraints (constraints) , _constraints (constraints)
{ {
cdebug_log(159,0) << "Tracks_Range::Locator()" << endl; cdebug_log(155,0) << "Tracks_Range::Locator()" << endl;
cdebug_log(159,0) << "* Constraints: " << _constraints << endl; cdebug_log(155,0) << "* Constraints: " << _constraints << endl;
_track = routingPlane->getTrackByPosition ( _constraints.getVMin() ); _track = routingPlane->getTrackByPosition ( _constraints.getVMin() );
if ( _track and (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNextTrack(); if ( _track and (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNextTrack();
if ( _track and (_track->getAxis() > _constraints.getVMax()) ) _track = NULL; if ( _track and (_track->getAxis() > _constraints.getVMax()) ) _track = NULL;
cdebug_log(159,0) << "_track: " << _track << endl;; cdebug_log(155,0) << "_track: " << _track << endl;;
} }
@ -147,9 +147,9 @@ namespace Katana {
, _inMinOptimal(true) , _inMinOptimal(true)
, _inMaxOptimal(true) , _inMaxOptimal(true)
{ {
cdebug_log(159,0) << "Tracks_Spiral::Locator()" << endl; cdebug_log(155,0) << "Tracks_Spiral::Locator()" << endl;
cdebug_log(159,0) << "* Optimal: " << _optimal << endl; cdebug_log(155,0) << "* Optimal: " << _optimal << endl;
cdebug_log(159,0) << "* Constraints: " << _constraints << endl; cdebug_log(155,0) << "* Constraints: " << _constraints << endl;
_minTrack = _maxTrack = routingPlane->getTrackByPosition ( _optimal.getCenter() ); _minTrack = _maxTrack = routingPlane->getTrackByPosition ( _optimal.getCenter() );
@ -169,8 +169,8 @@ namespace Katana {
if ( _minTrack && (_minTrack->getAxis() < _optimal.getVMin()) ) _inMinOptimal = false; if ( _minTrack && (_minTrack->getAxis() < _optimal.getVMin()) ) _inMinOptimal = false;
if ( _maxTrack && (_maxTrack->getAxis() > _optimal.getVMax()) ) _inMaxOptimal = false; if ( _maxTrack && (_maxTrack->getAxis() > _optimal.getVMax()) ) _inMaxOptimal = false;
cdebug_log(159,0) << "_minTrack: " << _minTrack << endl;; cdebug_log(155,0) << "_minTrack: " << _minTrack << endl;;
cdebug_log(159,0) << "_maxTrack: " << _maxTrack << endl;; cdebug_log(155,0) << "_maxTrack: " << _maxTrack << endl;;
} }
@ -210,13 +210,13 @@ namespace Katana {
void Tracks_Spiral::Locator::progress () void Tracks_Spiral::Locator::progress ()
{ {
cdebug_log(159,1) << "Track_Spiral::progress() - State:" << endl; cdebug_log(155,1) << "Track_Spiral::progress() - State:" << endl;
cdebug_log(159,0) << _onMin cdebug_log(155,0) << _onMin
<< " " << _minTrack << " " << _minTrack
<< " " << _maxTrack << endl; << " " << _maxTrack << endl;
if ( !isValid() ) { if ( !isValid() ) {
cdebug_tabw(159,-1); cdebug_tabw(155,-1);
return; return;
} }
@ -245,10 +245,10 @@ namespace Katana {
} }
} }
cdebug_log(159,0) << _onMin cdebug_log(155,0) << _onMin
<< " " << _minTrack << " " << _minTrack
<< " " << _maxTrack << endl; << " " << _maxTrack << endl;
cdebug_tabw(159,-1); cdebug_tabw(155,-1);
} }

View File

@ -37,6 +37,7 @@ namespace Katana {
using Hurricane::Record; using Hurricane::Record;
using Hurricane::DbU; using Hurricane::DbU;
using Hurricane::Point; using Hurricane::Point;
using Hurricane::Interval;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::NetRoutingState; using Hurricane::NetRoutingState;
using Hurricane::NetRoutingExtension; using Hurricane::NetRoutingExtension;
@ -44,6 +45,8 @@ namespace Katana {
class DataSymmetric { class DataSymmetric {
public:
typedef std::vector< std::array<AutoSegment*,2> > Paireds;
public: public:
static DataSymmetric* create ( Net* ); static DataSymmetric* create ( Net* );
public: public:
@ -52,11 +55,15 @@ namespace Katana {
inline Net* getNet () const; inline Net* getNet () const;
inline DbU::Unit getSymAxis () const; inline DbU::Unit getSymAxis () const;
inline Net* getSymNet () const; inline Net* getSymNet () const;
inline Point& getSymmetrical ( Point& ) const; inline const Paireds& getPaireds () const;
inline DbU::Unit getSymmetrical ( DbU::Unit ) const;
inline Point getSymmetrical ( const Point& ) const;
inline Interval getSymmetrical ( const Interval& ) const;
AutoSegment* getSymmetrical ( AutoSegment* ) const; AutoSegment* getSymmetrical ( AutoSegment* ) const;
void addSymmetrical ( AutoSegment* ); void addSymmetrical ( AutoSegment* );
inline void addReference ( AutoSegment* ); inline void addReference ( AutoSegment* );
inline void setValid ( bool ); inline void setValid ( bool );
inline void setSymAxis ( DbU::Unit );
bool checkPairing (); bool checkPairing ();
void print ( std::ostream& ) const; void print ( std::ostream& ) const;
Record* _getRecord () const; Record* _getRecord () const;
@ -64,28 +71,45 @@ namespace Katana {
private: private:
DataSymmetric ( Net* ); DataSymmetric ( Net* );
private: private:
bool _valid; bool _valid;
Net* _net; Net* _net;
Net* _symNet; Net* _symNet;
NetRoutingState* _state; NetRoutingState* _state;
std::vector< std::array<AutoSegment*,2> > _paireds; Paireds _paireds;
size_t _symIndex; size_t _symIndex;
}; };
inline bool DataSymmetric::isValid () const { return _valid; } inline bool DataSymmetric::isValid () const { return _valid; }
inline bool DataSymmetric::isSymVertical () const { return _state->isSymVertical(); } inline bool DataSymmetric::isSymVertical () const { return _state->isSymVertical(); }
inline Net* DataSymmetric::getNet () const { return _net; } inline const DataSymmetric::Paireds& DataSymmetric::getPaireds () const { return _paireds; }
inline DbU::Unit DataSymmetric::getSymAxis () const { return _state->getSymAxis(); } inline Net* DataSymmetric::getNet () const { return _net; }
inline Net* DataSymmetric::getSymNet () const { return _symNet; } inline DbU::Unit DataSymmetric::getSymAxis () const { return _state->getSymAxis(); }
inline void DataSymmetric::addReference ( AutoSegment* segment ) { _paireds.push_back( {segment,NULL} ); } inline void DataSymmetric::setSymAxis ( DbU::Unit axis ) { _state->setSymAxis(axis); }
inline void DataSymmetric::setValid ( bool state ) { _valid = state; } inline Net* DataSymmetric::getSymNet () const { return _symNet; }
inline void DataSymmetric::addReference ( AutoSegment* segment ) { _paireds.push_back( {segment,NULL} ); }
inline void DataSymmetric::setValid ( bool state ) { _valid = state; }
inline Point& DataSymmetric::getSymmetrical ( Point& point ) const inline DbU::Unit DataSymmetric::getSymmetrical ( DbU::Unit pos ) const
{ return 2*getSymAxis() - pos; }
inline Point DataSymmetric::getSymmetrical ( const Point& point ) const
{ {
if (_state->isSymVertical()) point.setX( 2*getSymAxis() - point.getX() ); Point symPoint ( point );
else point.setY( 2*getSymAxis() - point.getY() ); if (_state->isSymVertical()) symPoint.setX( 2*getSymAxis() - point.getX() );
return point; else symPoint.setY( 2*getSymAxis() - point.getY() );
return symPoint;
}
inline Interval DataSymmetric::getSymmetrical ( const Interval& interval ) const
{
DbU::Unit vmin = interval.getVMin();
if ( (vmin != DbU::Min) and (vmin != DbU::Max) ) vmin = 2*getSymAxis() - vmin;
DbU::Unit vmax = interval.getVMax();
if ( (vmax != DbU::Max) and (vmax != DbU::Max) ) vmax = 2*getSymAxis() - vmax;
return Interval( vmin, vmax );
} }

View File

@ -87,6 +87,8 @@ namespace Katana {
RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const; RoutingPlane* getRoutingPlaneByLayer ( const Layer* ) const;
Track* getTrackByPosition ( const Layer*, DbU::Unit axis, unsigned int mode=Constant::Nearest ) const; Track* getTrackByPosition ( const Layer*, DbU::Unit axis, unsigned int mode=Constant::Nearest ) const;
DataSymmetric* getDataSymmetric ( Net* ); DataSymmetric* getDataSymmetric ( Net* );
inline const std::map<Net*,DataSymmetric*>&
getSymmetrics () const;
inline void printConfiguration () const; inline void printConfiguration () const;
void printCompletion () const; void printCompletion () const;
void dumpMeasures ( std::ostream& ) const; void dumpMeasures ( std::ostream& ) const;
@ -161,6 +163,8 @@ namespace Katana {
inline size_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); } inline size_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); }
inline size_t KatanaEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); } inline size_t KatanaEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); }
inline unsigned int KatanaEngine::getRipupLimit ( unsigned int type ) const { return _configuration->getRipupLimit(type); } inline unsigned int KatanaEngine::getRipupLimit ( unsigned int type ) const { return _configuration->getRipupLimit(type); }
inline const std::map<Net*,DataSymmetric*>&
KatanaEngine::getSymmetrics () const { return _symmetrics; }
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 void KatanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } inline void KatanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }

View File

@ -95,31 +95,32 @@ namespace Katana {
, Packing = 2 , Packing = 2
}; };
public: public:
static NegociateWindow* create ( KatanaEngine* ); static NegociateWindow* create ( KatanaEngine* );
void destroy (); void destroy ();
inline bool isInterrupted () const; inline bool isInterrupted () const;
inline KatanaEngine* getKatanaEngine () const; inline KatanaEngine* getKatanaEngine () const;
Hurricane::Cell* getCell () const; Hurricane::Cell* getCell () const;
inline const vector<GCell*>& getGCells () const; inline const vector<GCell*>& getGCells () const;
inline RoutingEventQueue& getEventQueue (); inline RoutingEventQueue& getEventQueue ();
inline RoutingEventHistory& getEventHistory (); inline RoutingEventHistory& getEventHistory ();
inline RoutingEventLoop& getEventLoop (); inline RoutingEventLoop& getEventLoop ();
inline Stage getStage () const; inline Stage getStage () const;
void setGCells ( const vector<GCell*>& ); void setGCells ( const vector<GCell*>& );
inline void setInterrupt ( bool ); inline void setInterrupt ( bool );
inline void setStage ( Stage ); inline void setStage ( Stage );
double computeWirelength (); double computeWirelength ();
TrackElement* createTrackSegment ( AutoSegment*, unsigned int flags ); TrackElement* createTrackSegment ( AutoSegment*, unsigned int flags );
void addRoutingEvent ( TrackElement*, unsigned int level ); void addRoutingEvent ( TrackElement*, unsigned int level );
inline void rescheduleEvent ( RoutingEvent*, unsigned int level ); inline void rescheduleEvent ( RoutingEvent*, unsigned int level );
void run ( unsigned int flags ); void run ( unsigned int flags );
void printStatistics () const; void printStatistics () const;
void _createRouting ( Anabatic::GCell* ); void _createRouting ( Anabatic::GCell* );
void _pack ( size_t& count, bool last ); void _associateSymmetrics ();
size_t _negociate (); void _pack ( size_t& count, bool last );
Hurricane::Record* _getRecord () const; size_t _negociate ();
std::string _getString () const; Hurricane::Record* _getRecord () const;
inline std::string _getTypeName () const; std::string _getString () const;
inline std::string _getTypeName () const;
private: private:
// Attributes. // Attributes.

View File

@ -152,6 +152,8 @@ namespace Katana {
inline void setForcedToHint ( bool state = true ); inline void setForcedToHint ( bool state = true );
void setAxisHint ( DbU::Unit ); void setAxisHint ( DbU::Unit );
void setAxisHintFromParent (); void setAxisHintFromParent ();
inline void updateAxisHistory ();
inline void setInsertState ( unsigned int );
inline void incInsertState (); inline void incInsertState ();
inline void resetInsertState (); inline void resetInsertState ();
inline void setEventLevel ( unsigned int ); inline void setEventLevel ( unsigned int );
@ -162,8 +164,8 @@ namespace Katana {
string _getString () const; string _getString () const;
string _getTypeName () const; string _getTypeName () const;
private: private:
RoutingEvent ( TrackElement*, unsigned int mode ); RoutingEvent ( TrackElement*, unsigned int mode );
~RoutingEvent (); ~RoutingEvent ();
protected: protected:
// Attributes. // Attributes.
@ -234,6 +236,8 @@ namespace Katana {
inline void RoutingEvent::setRipedByLocal ( bool state ) { _ripedByLocal = state; } inline void RoutingEvent::setRipedByLocal ( bool state ) { _ripedByLocal = state; }
inline void RoutingEvent::setTracksFree ( unsigned int nb ) { _tracksFree = nb; } inline void RoutingEvent::setTracksFree ( unsigned int nb ) { _tracksFree = nb; }
inline void RoutingEvent::setForcedToHint ( bool state ) { _forceToHint = state; } inline void RoutingEvent::setForcedToHint ( bool state ) { _forceToHint = state; }
inline void RoutingEvent::updateAxisHistory () { _axisHistory = _segment->getAxis(); }
inline void RoutingEvent::setInsertState ( unsigned int state ) { _insertState = state; }
inline void RoutingEvent::incInsertState () { _insertState++; } inline void RoutingEvent::incInsertState () { _insertState++; }
inline void RoutingEvent::resetInsertState () { _insertState = 0; } inline void RoutingEvent::resetInsertState () { _insertState = 0; }
inline void RoutingEvent::setEventLevel ( unsigned int level ) { _eventLevel = level; } inline void RoutingEvent::setEventLevel ( unsigned int level ) { _eventLevel = level; }

View File

@ -17,10 +17,12 @@
#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;
@ -105,79 +107,111 @@ namespace Katana {
}; };
public: public:
SegmentFsm ( RoutingEvent* SegmentFsm ( RoutingEvent*
, RoutingEventQueue& , RoutingEventQueue&
, RoutingEventHistory& , RoutingEventHistory&
); );
inline bool isFullBlocked () const; inline bool isFullBlocked () const;
inline RoutingEvent* getEvent () const; inline bool isSymmetric () const;
inline RoutingEventQueue& getQueue () const; inline RoutingEvent* getEvent () const;
inline RoutingEventHistory& getHistory () const; inline RoutingEvent* getEvent1 () const;
inline unsigned int getState () const; inline RoutingEvent* getEvent2 () const;
inline DataNegociate* getData (); inline RoutingEventQueue& getQueue () const;
inline Interval& getConstraint (); inline RoutingEventHistory& getHistory () const;
inline Interval& getOptimal (); inline TrackElement* getSegment1 () const;
inline vector<TrackCost>& getCosts (); inline TrackElement* getSegment2 () const;
inline TrackCost& getCost ( size_t ); inline unsigned int getState () const;
inline Track* getTrack ( size_t ); inline DataNegociate* getData ();
inline size_t getBegin ( size_t ); inline DataNegociate* getData1 ();
inline size_t getEnd ( size_t ); inline DataNegociate* getData2 ();
inline vector<SegmentAction>& getActions (); inline Interval& getConstraint ();
inline void setState ( unsigned int ); inline Interval& getOptimal ();
void addAction ( TrackElement* inline vector< array<TrackCost,2> >& getCosts ();
, unsigned int type inline TrackCost& getCost ( size_t );
, DbU::Unit axisHint=0 inline TrackCost& getCost1 ( size_t );
, unsigned int toState =0 inline TrackCost& getCost2 ( size_t );
); inline Track* getTrack ( size_t );
void doActions (); inline size_t getBegin ( size_t );
inline void clearActions (); inline size_t getEnd ( size_t );
bool insertInTrack ( size_t ); inline vector<SegmentAction>& getActions ();
bool conflictSolveByHistory (); inline void setState ( unsigned int );
bool conflictSolveByPlaceds (); void setDataState ( unsigned int );
bool solveTerminalVsGlobal (); void addAction ( TrackElement*
bool desaturate (); , unsigned int type
bool slackenTopology ( unsigned int flags=0 ); , DbU::Unit axisHint=0
bool solveFullBlockages (); , unsigned int toState =0
private: );
bool _slackenStrap ( TrackElement*& void doActions ();
, DataNegociate*& inline void clearActions ();
, unsigned int flags ); inline SegmentFsm& useEvent1 ();
bool _slackenLocal ( TrackElement*& inline SegmentFsm& useEvent2 ();
, DataNegociate*& void incRipupCount ();
, unsigned int flags ); bool insertInTrack ( size_t );
bool _slackenGlobal ( TrackElement*& void bindToTrack ( size_t );
, DataNegociate*& void moveToTrack ( size_t );
, unsigned int flags ); void ripupPerpandiculars ();
private: bool canRipup ( unsigned int flags=0 );
RoutingEvent* _event; bool conflictSolveByHistory ();
RoutingEventQueue& _queue; bool conflictSolveByPlaceds ();
RoutingEventHistory& _history; bool solveTerminalVsGlobal ();
unsigned int _state; bool desaturate ();
DataNegociate* _data; bool slackenTopology ( unsigned int flags=0 );
Interval _constraint; bool solveFullBlockages ();
Interval _optimal; private:
vector<TrackCost> _costs; bool _slackenStrap ( TrackElement*&
vector<SegmentAction> _actions; , DataNegociate*&
bool _fullBlocked; , unsigned int flags );
bool _slackenLocal ( TrackElement*&
, DataNegociate*&
, unsigned int flags );
bool _slackenGlobal ( TrackElement*&
, DataNegociate*&
, unsigned int flags );
private:
RoutingEvent* _event1;
RoutingEvent* _event2;
RoutingEventQueue& _queue;
RoutingEventHistory& _history;
unsigned int _state;
DataNegociate* _data1;
DataNegociate* _data2;
Interval _constraint;
Interval _optimal;
vector< array<TrackCost,2> > _costs;
vector<SegmentAction> _actions;
bool _fullBlocked;
bool _sameAxis;
bool _useEvent2;
}; };
inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } inline bool SegmentFsm::isSymmetric () const { return _event2 != NULL; }
inline RoutingEvent* SegmentFsm::getEvent () const { return _event; } inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); }
inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } inline RoutingEvent* SegmentFsm::getEvent () const { return (_useEvent2) ? _event2 : _event1; }
inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } inline RoutingEvent* SegmentFsm::getEvent1 () const { return _event1; }
inline unsigned int SegmentFsm::getState () const { return _state; } inline RoutingEvent* SegmentFsm::getEvent2 () const { return _event2; }
inline DataNegociate* SegmentFsm::getData () { return _data; } inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; }
inline Interval& SegmentFsm::getConstraint () { return _constraint; } inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; }
inline Interval& SegmentFsm::getOptimal () { return _optimal; } inline unsigned int SegmentFsm::getState () const { return _state; }
inline vector<TrackCost>& SegmentFsm::getCosts () { return _costs; } inline TrackElement* SegmentFsm::getSegment1 () const { return _event1->getSegment(); }
inline TrackCost& SegmentFsm::getCost ( size_t i ) { return _costs[i]; } inline TrackElement* SegmentFsm::getSegment2 () const { return (_event2) ? _event2->getSegment() : NULL; }
inline Track* SegmentFsm::getTrack ( size_t i ) { return _costs[i].getTrack(); } inline DataNegociate* SegmentFsm::getData () { return (_useEvent2) ? _data2 : _data1; }
inline size_t SegmentFsm::getBegin ( size_t i ) { return _costs[i].getBegin(); } inline DataNegociate* SegmentFsm::getData1 () { return _data1; }
inline size_t SegmentFsm::getEnd ( size_t i ) { return _costs[i].getEnd(); } inline DataNegociate* SegmentFsm::getData2 () { return _data2; }
inline vector<SegmentAction>& SegmentFsm::getActions () { return _actions; } inline Interval& SegmentFsm::getConstraint () { return _constraint; }
inline void SegmentFsm::setState ( unsigned int state ) { _state = state; } inline Interval& SegmentFsm::getOptimal () { return _optimal; }
inline void SegmentFsm::clearActions () { _actions.clear(); } inline vector< array<TrackCost,2> >& SegmentFsm::getCosts () { return _costs; }
inline TrackCost& SegmentFsm::getCost ( size_t i ) { return _costs[i][0]; }
inline TrackCost& SegmentFsm::getCost1 ( size_t i ) { return _costs[i][0]; }
inline TrackCost& SegmentFsm::getCost2 ( size_t i ) { return _costs[i][1]; }
inline Track* SegmentFsm::getTrack ( size_t i ) { return (_useEvent2) ? _costs[i][1].getTrack() : _costs[i][0].getTrack(); }
inline size_t SegmentFsm::getBegin ( size_t i ) { return (_useEvent2) ? _costs[i][1].getBegin() : _costs[i][0].getBegin(); }
inline size_t SegmentFsm::getEnd ( size_t i ) { return (_useEvent2) ? _costs[i][1].getEnd () : _costs[i][0].getEnd (); }
inline vector<SegmentAction>& SegmentFsm::getActions () { return _actions; }
inline void SegmentFsm::setState ( unsigned int 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

@ -10,7 +10,7 @@
// | Author : Jean-Paul CHAPUT | // | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== | // | =============================================================== |
// | C++ Header : "./katana/TrackCost.h" | // | C++ Header : "./katana/TrackCost.h" |
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
@ -61,9 +61,7 @@ namespace Katana {
}; };
public: public:
TrackCost ( Track* track TrackCost ( Track* track );
, Net* net
);
TrackCost ( Track* track TrackCost ( Track* track
, const Interval& interval , const Interval& interval
, size_t begin , size_t begin
@ -113,6 +111,7 @@ namespace Katana {
inline void setLonguestOverlap ( DbU::Unit ); inline void setLonguestOverlap ( DbU::Unit );
inline void mergeRipupCount ( int ); inline void mergeRipupCount ( int );
inline void mergeDataState ( unsigned int ); inline void mergeDataState ( unsigned int );
void merge ( const TrackCost& );
void consolidate (); void consolidate ();
Record* _getRecord () const; Record* _getRecord () const;
string _getString () const; string _getString () const;

View File

@ -111,6 +111,7 @@ namespace Katana {
inline bool isBlockage () const; inline bool isBlockage () const;
inline bool isLocked () const; inline bool isLocked () const;
inline bool isRouted () const; inline bool isRouted () const;
virtual bool hasSymmetric () const;
inline bool hasSourceDogleg () const; inline bool hasSourceDogleg () const;
inline bool hasTargetDogleg () const; inline bool hasTargetDogleg () const;
inline bool canRipple () const; inline bool canRipple () const;
@ -151,6 +152,7 @@ namespace Katana {
virtual unsigned int getDoglegLevel () const; virtual unsigned int getDoglegLevel () const;
virtual TrackElement* getSourceDogleg (); virtual TrackElement* getSourceDogleg ();
virtual TrackElement* getTargetDogleg (); virtual TrackElement* getTargetDogleg ();
virtual TrackElement* getSymmetric ();
virtual TrackElements getPerpandiculars (); virtual TrackElements getPerpandiculars ();
// Mutators. // Mutators.
inline void setFlags ( unsigned int ); inline void setFlags ( unsigned int );
@ -158,6 +160,7 @@ namespace Katana {
inline void setRouted (); inline void setRouted ();
virtual void setTrack ( Track* ); virtual void setTrack ( Track* );
inline void setIndex ( size_t ); inline void setIndex ( size_t );
virtual void setSymmetric ( TrackElement* );
virtual void updateFreedomDegree (); virtual void updateFreedomDegree ();
virtual void setDoglegLevel ( unsigned int ); virtual void setDoglegLevel ( unsigned int );
virtual void swapTrack ( TrackElement* ); virtual void swapTrack ( TrackElement* );

View File

@ -72,6 +72,7 @@ namespace Katana {
virtual bool isUTurn () const; virtual bool isUTurn () const;
virtual bool isUserDefined () const; virtual bool isUserDefined () const;
// Predicates. // Predicates.
virtual bool hasSymmetric () const;
virtual bool canDogleg (); virtual bool canDogleg ();
virtual bool canDogleg ( Interval ); virtual bool canDogleg ( Interval );
virtual bool canDogleg ( Anabatic::GCell*, unsigned int flags=0 ); virtual bool canDogleg ( Anabatic::GCell*, unsigned int flags=0 );
@ -100,10 +101,12 @@ namespace Katana {
virtual size_t getGCells ( vector<GCell*>& ) const; virtual size_t getGCells ( vector<GCell*>& ) const;
virtual TrackElement* getSourceDogleg (); virtual TrackElement* getSourceDogleg ();
virtual TrackElement* getTargetDogleg (); virtual TrackElement* getTargetDogleg ();
virtual TrackElement* getSymmetric ();
virtual TrackElements getPerpandiculars (); virtual TrackElements getPerpandiculars ();
virtual size_t getPerpandicularsBound ( set<TrackElement*>& ); virtual size_t getPerpandicularsBound ( set<TrackElement*>& );
// Mutators. // Mutators.
virtual void setTrack ( Track* ); virtual void setTrack ( Track* );
virtual void setSymmetric ( TrackElement* );
virtual void updateFreedomDegree (); virtual void updateFreedomDegree ();
virtual void setDoglegLevel ( unsigned int ); virtual void setDoglegLevel ( unsigned int );
virtual void swapTrack ( TrackElement* ); virtual void swapTrack ( TrackElement* );
@ -133,6 +136,7 @@ namespace Katana {
// Attributes. // Attributes.
static size_t _allocateds; static size_t _allocateds;
AutoSegment* _base; AutoSegment* _base;
TrackSegment* _symmetric;
unsigned long _freedomDegree; unsigned long _freedomDegree;
DbU::Unit _ppitch; DbU::Unit _ppitch;
DataNegociate* _data; DataNegociate* _data;