Added a new post-routing stage "realign" in Katana.
When a segment is placed only once (which is to say it is nerver ripped up) it can sometimes end-up in a non-optimal place. We now add a stage in Katana where each segment is "re-placed" in order to maximise alignment on it's neighbor. This is a new stage added to both RoutingEvent and NegociateWidow. Segments are replaced *only* in free space, they will not ripup *other* segments, except for their own perpandiculars. We exclude from re-placement globals (unlikely to move) and segment that have reduced perpandiculars which *must* not be elongated and potentially raised. Add a new katana setting to enable/disable the realign stage (enabled by default: - "katana.runRealignStage" ( = True )
This commit is contained in:
parent
4b6da7bde9
commit
2a1f014491
|
@ -53,6 +53,7 @@ namespace Katana {
|
|||
, _bloatOverloadAdd (Cfg::getParamInt ("katana.bloatOverloadAdd" , 4)->asInt())
|
||||
, _flags (0)
|
||||
, _profileEventCosts (Cfg::getParamBool("katana.profileEventCosts" ,false )->asBool())
|
||||
, _runRealignStage (Cfg::getParamBool("katana.runRealignStage" ,true )->asBool())
|
||||
{
|
||||
_ripupLimits[StrapRipupLimit] = Cfg::getParamInt("katana.strapRipupLimit" ,16)->asInt();
|
||||
_ripupLimits[LocalRipupLimit] = Cfg::getParamInt("katana.localRipupLimit" , 7)->asInt();
|
||||
|
@ -100,6 +101,7 @@ namespace Katana {
|
|||
, _bloatOverloadAdd (other._bloatOverloadAdd)
|
||||
, _flags (other._flags)
|
||||
, _profileEventCosts (other._profileEventCosts)
|
||||
, _runRealignStage (other._runRealignStage)
|
||||
{
|
||||
_ripupLimits[StrapRipupLimit] = other._ripupLimits[StrapRipupLimit];
|
||||
_ripupLimits[LocalRipupLimit] = other._ripupLimits[LocalRipupLimit];
|
||||
|
|
|
@ -681,6 +681,43 @@ namespace Katana {
|
|||
if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true );
|
||||
}
|
||||
|
||||
if (_katana->getConfiguration()->runRealignStage()) {
|
||||
cmess1 << " o Realign Stage." << endl;
|
||||
|
||||
cdebug_log(159,0) << "Loadind realign queue." << endl;
|
||||
RoutingEvent::setStage( RoutingEvent::Realign );
|
||||
for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) {
|
||||
RoutingEvent* event = _eventHistory.getNth(i);
|
||||
if (not event->isCloned() and event->getSegment()->canRealign())
|
||||
event->reschedule( _eventQueue, 0 );
|
||||
}
|
||||
_eventQueue.commit();
|
||||
cmess2 << " <realign.queue:" << right << setw(8) << setfill('0')
|
||||
<< _eventQueue.size() << ">" << setfill(' ') << endl;
|
||||
count = 0;
|
||||
while ( not _eventQueue.empty() and not isInterrupted() ) {
|
||||
RoutingEvent* event = _eventQueue.pop();
|
||||
if (tty::enabled()) {
|
||||
cmess2 << " <realign.event:" << tty::bold << setw(8) << setfill('0')
|
||||
<< RoutingEvent::getProcesseds() << tty::reset
|
||||
<< " remains:" << right << setw(8) << setfill('0')
|
||||
<< _eventQueue.size() << ">"
|
||||
<< setfill(' ') << tty::reset << tty::cr;
|
||||
cmess2.flush();
|
||||
} else {
|
||||
cmess2 << " <realign.event:" << setw(8) << setfill('0')
|
||||
<< RoutingEvent::getProcesseds() << setfill(' ') << " "
|
||||
<< event->getEventLevel() << ":" << event->getPriority() << "> "
|
||||
<< event->getSegment()
|
||||
<< endl;
|
||||
cmess2.flush();
|
||||
}
|
||||
event->process( _eventQueue, _eventHistory, _eventLoop );
|
||||
count++;
|
||||
if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true );
|
||||
}
|
||||
}
|
||||
|
||||
if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl;
|
||||
//}
|
||||
|
||||
|
|
|
@ -377,6 +377,8 @@ namespace Katana {
|
|||
_segment->getDataNegociate()->setState( DataNegociate::Repair );
|
||||
} else if (getStage() == RoutingEvent::Pack) {
|
||||
fork->setMode( RoutingEvent::Pack );
|
||||
} else if (getStage() == RoutingEvent::Realign) {
|
||||
fork->setMode( RoutingEvent::Realign );
|
||||
}
|
||||
|
||||
queue.repush( fork );
|
||||
|
@ -470,6 +472,7 @@ namespace Katana {
|
|||
case Negociate: _processNegociate( queue, history ); break;
|
||||
case Pack: _processPack ( queue, history ); break;
|
||||
case Repair: _processRepair ( queue, history ); break;
|
||||
case Realign: _processRealign ( queue, history ); break;
|
||||
default:
|
||||
cerr << Bug( "RoutingEvent::process() - Unknown mode value:%d.", _mode ) << endl;
|
||||
break;
|
||||
|
@ -661,6 +664,31 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
void RoutingEvent::_processRealign ( RoutingEventQueue& queue, RoutingEventHistory& history )
|
||||
{
|
||||
cdebug_log(159,0) << "* Mode:Realign." << endl;
|
||||
|
||||
SegmentFsm fsm ( this, queue, history );
|
||||
if (fsm.getState() == SegmentFsm::MissingData ) return;
|
||||
if (fsm.getState() == SegmentFsm::EmptyTrackList) return;
|
||||
if (fsm.isSymmetric()) return;
|
||||
|
||||
cdebug_log(159,0) << "| Candidate Tracks:" << endl;
|
||||
size_t itrack = 0;
|
||||
for ( itrack = 0 ; itrack < fsm.getCosts().size() ; itrack++ )
|
||||
cdebug_log(159,0) << "| " << itrack << ":" << fsm.getCost(itrack) << endl;
|
||||
|
||||
if ( fsm.getCosts().size()
|
||||
and fsm.getCost(0)->isFree()
|
||||
and (fsm.getCost(0)->getTrack() != getSegment()->getTrack())) {
|
||||
cdebug_log(159,0) << "Insert in free space." << endl;
|
||||
fsm.moveToTrack( 0 );
|
||||
fsm.doActions();
|
||||
queue.commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RoutingEvent::revalidate ()
|
||||
{
|
||||
if (_segment->isNonPref()) { _revalidateNonPref(); return; }
|
||||
|
|
|
@ -636,7 +636,8 @@ namespace Katana {
|
|||
and (_data1->getState() < DataNegociate::Minimize)
|
||||
and (_data1->getRipupCount() < 5))
|
||||
? TrackCost::DiscardGlobals : 0;
|
||||
flags |= (RoutingEvent::getStage() == RoutingEvent::Repair) ? TrackCost::IgnoreSharedLength : 0;
|
||||
flags |= (RoutingEvent::getStage() == RoutingEvent::Repair ) ? TrackCost::IgnoreSharedLength : 0;
|
||||
flags |= (RoutingEvent::getStage() == RoutingEvent::Realign) ? TrackCost::IgnoreTerminals : 0;
|
||||
|
||||
if (flags & TrackCost::DiscardGlobals) {
|
||||
cdebug_log(159,0) << "TrackCost::Compare() - DiscardGlobals" << endl;
|
||||
|
|
|
@ -404,13 +404,13 @@ namespace Katana {
|
|||
}
|
||||
|
||||
|
||||
void Session::_addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis )
|
||||
void Session::_addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis, bool check )
|
||||
{
|
||||
cdebug_log(159,0) << "addInsertEvent() " << segment
|
||||
<< "\n @" << DbU::getValueString(axis)
|
||||
<< " " << track << endl;
|
||||
|
||||
if ( segment->getTrack() != NULL ) {
|
||||
if ( check and (segment->getTrack() != NULL) ) {
|
||||
cerr << Bug("Session::addInsertEvent(): Segment already in Track."
|
||||
"\n %s."
|
||||
"\n to %s."
|
||||
|
@ -460,8 +460,7 @@ namespace Katana {
|
|||
} else {
|
||||
_addRemoveEvent( segment );
|
||||
}
|
||||
|
||||
_addInsertEvent( segment, track, axis );
|
||||
_addInsertEvent( segment, track, axis, false );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -374,11 +374,11 @@ namespace Katana {
|
|||
Interval freeInterval = getFreeInterval( interval.getCenter(), cost.getNet() );
|
||||
|
||||
if (not freeInterval.contains(interval)) {
|
||||
getOverlapBounds( cost.getInterval(), begin, end );
|
||||
cost.setFreeLength( 0 );
|
||||
} else {
|
||||
cost.setFreeLength( freeInterval.getSize() );
|
||||
}
|
||||
getOverlapBounds( cost.getInterval(), begin, end );
|
||||
cost.setTrack( const_cast<Track*>(this), begin, end );
|
||||
|
||||
cdebug_log(155,1) << "addOverlapCost() @" << DbU::getValueString(_axis)
|
||||
|
@ -386,6 +386,7 @@ namespace Katana {
|
|||
<< ":" << DbU::getValueString(interval.getVMax())
|
||||
<< "] <-> [" << begin << ":" << end << "]"
|
||||
<< endl;
|
||||
cdebug_log(155,0) << "initial:" << &cost << endl;
|
||||
cdebug_log(155,0) << "freeInterval [" << DbU::getValueString(freeInterval.getVMin())
|
||||
<< ":" << DbU::getValueString(freeInterval.getVMax()) << "]"
|
||||
<< endl;
|
||||
|
@ -409,7 +410,20 @@ namespace Katana {
|
|||
}
|
||||
|
||||
if (begin == npos) {
|
||||
if (not _segments.empty()
|
||||
and (_segments.back()->getNet() == cost.getNet())
|
||||
and (cost.getRefElement()->getAxis() != getAxis())
|
||||
) {
|
||||
Interval overlap = interval.getIntersection( _segments.back()->getCanonicalInterval() );
|
||||
cdebug_log(155,0) << "overlap:" << overlap
|
||||
<< " size:" << DbU::getValueString(overlap.getSize()) << endl;
|
||||
if (overlap.getSize() > 0) {
|
||||
cdebug_log(155,0) << "Same net overlap, increase delta shared." << endl;
|
||||
cost.incDeltaShared ( overlap.getSize() );
|
||||
}
|
||||
}
|
||||
cdebug_log(155,0) << " begin == npos (after last TrackElement)." << endl;
|
||||
cdebug_log(155,0) << " current:" << &cost << endl;
|
||||
cdebug_tabw(155,-1);
|
||||
return cost;
|
||||
}
|
||||
|
@ -420,7 +434,9 @@ namespace Katana {
|
|||
<< " size:" << DbU::getValueString(overlap.getSize()) << endl;
|
||||
if (overlap.getSize() == 0) continue;
|
||||
|
||||
if (_segments[begin]->getNet() == cost.getNet()) {
|
||||
if ( (_segments[begin]->getNet() == cost.getNet())
|
||||
and ((cost.getRefElement()->getAxis() != getAxis())
|
||||
or not _segments[begin]->isNonPref() ) ) {
|
||||
cdebug_log(155,0) << "Same net overlap, increase delta shared." << endl;
|
||||
cost.incDeltaShared ( overlap.getSize() );
|
||||
}
|
||||
|
|
|
@ -132,8 +132,10 @@ namespace Katana {
|
|||
|
||||
if ( lhs->isOverlap() xor rhs->isOverlap() ) return rhs->isOverlap();
|
||||
|
||||
if ( lhs->_terminals < rhs->_terminals ) return true;
|
||||
if ( lhs->_terminals > rhs->_terminals ) return false;
|
||||
if (not (_flags & TrackCost::IgnoreTerminals)) {
|
||||
if ( lhs->_terminals < rhs->_terminals ) return true;
|
||||
if ( lhs->_terminals > rhs->_terminals ) return false;
|
||||
}
|
||||
|
||||
if (lhs->_delta != rhs->_delta) {
|
||||
//cdebug_log(155,0) << "TrackCost::Compare() lhs->_delta:" << lhs->_delta << " rhs->_delta:" << rhs->_delta << endl;
|
||||
|
@ -203,7 +205,8 @@ namespace Katana {
|
|||
void TrackCost::consolidate ()
|
||||
{
|
||||
if ( not isInfinite() and not isHardOverlap() ) {
|
||||
cdebug_log(159,0) << "TrackCost::consolidate() " << _delta << " - " << _deltaShared << endl;
|
||||
cdebug_log(159,0) << "TrackCost::consolidate() " << DbU::getValueString(_delta)
|
||||
<< " - " << DbU::getValueString(_deltaShared) << endl;
|
||||
//_deltaPerpand += - (_deltaShared << 1);
|
||||
_delta -= _deltaShared;
|
||||
//if (_delta > 0) _delta -= _deltaShared;
|
||||
|
@ -270,8 +273,8 @@ namespace Katana {
|
|||
s += string ( (isAnalog ())?"a":"-" );
|
||||
s += string ( (isShortNet ())?"N":"-" );
|
||||
s += " t:" + getString(_terminals);
|
||||
s += "/d:" + /*DbU::getValueString(_delta)*/ getString(_delta);
|
||||
s += "-" + /*DbU::getValueString(_deltaShared)*/ getString(_deltaShared);
|
||||
s += "/d:" + /*DbU::getValueString(_delta)*/ DbU::getValueString(_delta);
|
||||
s += "-" + /*DbU::getValueString(_deltaShared)*/ DbU::getValueString(_deltaShared);
|
||||
s += "/aw:" + DbU::getValueString(_axisWeight);
|
||||
s += "/dp:" + DbU::getValueString(_deltaPerpand);
|
||||
s += "/df:" + DbU::getValueString(_distanceToFixed);
|
||||
|
|
|
@ -161,6 +161,7 @@ namespace Katana {
|
|||
bool TrackElement::canDogleg () { return false; };
|
||||
bool TrackElement::canDogleg ( Interval ) { return false; };
|
||||
bool TrackElement::canDogleg ( Anabatic::GCell*, Flags ) { return false; };
|
||||
bool TrackElement::canRealign () const { return false; };
|
||||
// Accessors.
|
||||
unsigned long TrackElement::getId () const { return 0; }
|
||||
unsigned long TrackElement::getFreedomDegree () const { return 0; }
|
||||
|
|
|
@ -601,6 +601,16 @@ namespace Katana {
|
|||
|
||||
float TrackSegment::getMaxUnderDensity ( Flags flags ) const
|
||||
{ return _base->getMaxUnderDensity( flags ); }
|
||||
|
||||
|
||||
bool TrackSegment::canRealign () const
|
||||
{
|
||||
if (isGlobal() or isNonPref() or isReduced()) return false;
|
||||
for ( TrackElement* perpandicular : const_cast<TrackSegment*>(this)->getPerpandiculars() ) {
|
||||
if (perpandicular->isReduced()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TrackSegment::canPivotUp ( float reserve, Flags flags ) const
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef KATANA_CONFIGURATION_H
|
||||
#define KATANA_CONFIGURATION_H
|
||||
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include "anabatic/Configuration.h"
|
||||
#include "katana/Constants.h"
|
||||
|
@ -67,6 +65,7 @@ namespace Katana {
|
|||
inline bool useGlobalEstimate () const;
|
||||
inline bool useStaticBloatProfile () const;
|
||||
inline bool profileEventCosts () const;
|
||||
inline bool runRealignStage () const;
|
||||
// Methods.
|
||||
inline Anabatic::Configuration* base ();
|
||||
inline const Anabatic::Configuration* base () const;
|
||||
|
@ -94,6 +93,7 @@ namespace Katana {
|
|||
inline void setFlags ( unsigned int );
|
||||
inline void unsetFlags ( unsigned int );
|
||||
inline void setProfileEventCosts ( bool );
|
||||
inline void setRunRealignStage ( bool );
|
||||
virtual void print ( Cell* ) const;
|
||||
virtual Record* _getRecord () const;
|
||||
virtual string _getString () const;
|
||||
|
@ -114,6 +114,7 @@ namespace Katana {
|
|||
uint32_t _bloatOverloadAdd;
|
||||
unsigned int _flags;
|
||||
bool _profileEventCosts;
|
||||
bool _runRealignStage;
|
||||
private:
|
||||
Configuration ( const Configuration& other );
|
||||
Configuration& operator= ( const Configuration& );
|
||||
|
@ -142,9 +143,11 @@ namespace Katana {
|
|||
inline bool Configuration::useGlobalEstimate () const { return _flags & UseGlobalEstimate; }
|
||||
inline bool Configuration::useStaticBloatProfile () const { return _flags & UseStaticBloatProfile; }
|
||||
inline bool Configuration::profileEventCosts () const { return _profileEventCosts; }
|
||||
inline bool Configuration::runRealignStage () const { return _runRealignStage; }
|
||||
inline void Configuration::setFlags ( unsigned int flags ) { _flags |= flags; }
|
||||
inline void Configuration::unsetFlags ( unsigned int flags ) { _flags &= ~flags; }
|
||||
inline void Configuration::setProfileEventCosts ( bool state ) { _profileEventCosts = state; }
|
||||
inline void Configuration::setRunRealignStage ( bool state ) { _runRealignStage = state; }
|
||||
|
||||
|
||||
|
||||
|
@ -152,6 +155,3 @@ namespace Katana {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Katana::Configuration);
|
||||
|
||||
|
||||
#endif // KATANA_CONFIGURATION_H
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef KATANA_ROUTING_EVENT_H
|
||||
#define KATANA_ROUTING_EVENT_H
|
||||
|
||||
#pragma once
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
@ -94,7 +92,7 @@ namespace Katana {
|
|||
friend class Compare;
|
||||
|
||||
public:
|
||||
enum Mode { Negociate=1, Pack=2, Repair=3 };
|
||||
enum Mode { Negociate=1, Pack=2, Repair=3, Realign=4 };
|
||||
|
||||
public:
|
||||
static uint32_t getStage ();
|
||||
|
@ -163,6 +161,7 @@ namespace Katana {
|
|||
void _processNegociate ( RoutingEventQueue&, RoutingEventHistory& );
|
||||
void _processPack ( RoutingEventQueue&, RoutingEventHistory& );
|
||||
void _processRepair ( RoutingEventQueue&, RoutingEventHistory& );
|
||||
void _processRealign ( RoutingEventQueue&, RoutingEventHistory& );
|
||||
Record* _getRecord () const;
|
||||
string _getString () const;
|
||||
string _getTypeName () const;
|
||||
|
@ -287,6 +286,3 @@ namespace Katana {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Katana::RoutingEvent);
|
||||
|
||||
|
||||
#endif // KATANA_ROUTING_EVENT_H
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace Katana {
|
|||
inline static Interval& toAxisInterval ( Interval&, size_t depth );
|
||||
inline static void addIndirectInvalid ( TrackElement* );
|
||||
inline static void addInsertEvent ( TrackMarker* , Track* );
|
||||
inline static void addInsertEvent ( TrackElement* , Track*, DbU::Unit axis );
|
||||
inline static void addInsertEvent ( TrackElement* , Track*, DbU::Unit axis, bool check=true );
|
||||
inline static void addRemoveEvent ( TrackElement* );
|
||||
inline static void addMoveEvent ( TrackElement* , Track*, DbU::Unit axis );
|
||||
inline static void addSortEvent ( Track*, bool forced=false );
|
||||
|
@ -107,7 +107,7 @@ namespace Katana {
|
|||
_getIndirectInvalids ();
|
||||
inline void _addIndirectInvalid ( TrackElement* );
|
||||
void _addInsertEvent ( TrackMarker* , Track* );
|
||||
void _addInsertEvent ( TrackElement* , Track*, DbU::Unit axis );
|
||||
void _addInsertEvent ( TrackElement* , Track*, DbU::Unit axis, bool check );
|
||||
void _addRemoveEvent ( TrackElement* );
|
||||
void _addMoveEvent ( TrackElement* , Track*, DbU::Unit axis );
|
||||
void _addSortEvent ( Track*, bool forced );
|
||||
|
@ -191,8 +191,8 @@ namespace Katana {
|
|||
inline void Session::addInsertEvent ( TrackMarker* marker, Track* track )
|
||||
{ get("addInsertEvent(TrackMarker*)")->_addInsertEvent(marker,track); }
|
||||
|
||||
inline void Session::addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis )
|
||||
{ get("addInsertEvent(TrackElement*)")->_addInsertEvent(segment,track,axis); }
|
||||
inline void Session::addInsertEvent ( TrackElement* segment, Track* track, DbU::Unit axis, bool check )
|
||||
{ get("addInsertEvent(TrackElement*)")->_addInsertEvent(segment,track,axis,check); }
|
||||
|
||||
inline void Session::addRemoveEvent ( TrackElement* segment )
|
||||
{ get("addRemoveEvent()")->_addRemoveEvent(segment); }
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef KATANA_TRACK_COST_H
|
||||
#define KATANA_TRACK_COST_H
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include "hurricane/Interval.h"
|
||||
|
@ -61,6 +59,7 @@ namespace Katana {
|
|||
, OverlapGlobal = (1 << 16)
|
||||
, GlobalEnclosed = (1 << 17)
|
||||
, AtRipupLimit = (1 << 18)
|
||||
, IgnoreTerminals = (1 << 19)
|
||||
, MergeMask = ForGlobal |Blockage|Fixed |Infinite
|
||||
|HardOverlap |Overlap |RightOverlap|LeftOverlap|OverlapGlobal
|
||||
|GlobalEnclosed |AtRipupLimit
|
||||
|
@ -326,6 +325,3 @@ namespace Katana {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Katana::TrackCost);
|
||||
|
||||
|
||||
#endif // KATANA_TRACK_COST_H
|
||||
|
|
|
@ -142,6 +142,7 @@ namespace Katana {
|
|||
virtual bool canDogleg ();
|
||||
virtual bool canDogleg ( Interval );
|
||||
virtual bool canDogleg ( Anabatic::GCell*, Flags flags=0 );
|
||||
virtual bool canRealign () const;
|
||||
// Accessors
|
||||
inline Observer<TrackElement>* getObserver ();
|
||||
virtual unsigned long getId () const;
|
||||
|
|
|
@ -93,6 +93,7 @@ namespace Katana {
|
|||
virtual bool canPivotDown ( float reserve, Flags ) const;
|
||||
virtual bool canMoveUp ( float reserve, Flags ) const;
|
||||
virtual bool canSlacken () const;
|
||||
virtual bool canRealign () const;
|
||||
virtual float getMaxUnderDensity ( Flags ) const;
|
||||
virtual unsigned long getId () const;
|
||||
virtual Flags getDirection () const;
|
||||
|
|
Loading…
Reference in New Issue