coriolis/kite/doc/RoutingEvent.dox

598 lines
26 KiB
Plaintext
Raw Normal View History

// -*- C++ -*-
namespace Kite {
/*! \class RoutingEvent
* \brief Manage TrackSegment routing requests.
*
* The \RoutingEvent is the workhorse of Kite. A \RoutingEvent is
* associated to one \TrackSegment. One \TrackSegment could be
* associated to many \RoutingEvent in the queue, but only one
* of those is active (marked as unprocessed).
*
* \see ClassManipulator.
*
* \section secProcessAlgorithm Description of the process() method
*
\code
void RoutingEvent::process ()
{
if ( isProcessed() ) return;
setProcessed ();
incRipupCount ();
if ( getRipupCount() > MAX_RIPUP_COUNT ) {
// We are *not* in ripup mode.
// The event's segment has to be topologically modified.
modifyTopology ( _segment );
} else {
// We are in ripup mode.
// Other overlaping segments are to be removeds/pusheds. It can result in
// segment breaking *if* other segment came from an already routed GCell.
// optimal, constraint, perpandicular.
computeAllIntervals ();
// Find & order all candidates Tracks.
candidates = computeCostOnCandidateTracks ();
sort ( candidates );
if ( candidates[0].isFree() ) {
// Case -A.1- "Free Track".
candidate[0].insert ( _segment );
} else if ( candidates[0].isSoftOverlap()
|| candidates[0].isHardOverlap() ) {
// Case -A.2- "Soft Overlap".
// Case -A.3- "Hard Overlap".
for ( size_t i=0 ; i<candidates.size() ; i++ ) {
if ( candidates[0].insertInTrack ( _segment ) ) {
break;
}
}
} else {
// Case -B- "Infinite Cost".
// Attention: meaning's changed, *infinite* only in case of
// conflict with a *fixed* other segment.
modifyTopology ( _segment );
}
}
// Restore Track coherency before processing any other event.
Session::revalidate ();
}
\endcode
* \section secRoutingIntervalToDo ToDo
*
* <ul>
* <li>New \c isLocal() method on \TrackSegment. Tells if the \TrackSegment
* is associated only to local AutoSegment.
* <li>Increase the overlap cost of a \TrackSegment from an already routed
* GCell routing set.
* </ul>
*
*
* \section secRoutingEventInterval The various intervals of a RoutingEvent
*
* The three Intervals controlling a RoutingEvent : all those intervals
* defines the track range in which the \TrackSegment could be inserted.
* <ul>
* <li>The <i>optimal</i> interval : where the \Net wirelength will be
* minimal (comes from \c Katabatic::AutoSegment).
* <li>The <i>constraint</i> interval : the interval outside of which
* the \Net connexity would be broken. This is the bigger interval
* but it must be strictly respected (also comes from
* \c Katabatic::AutoSegment).
* <li>The <i>perpandicular</i> interval : for each perpandicular
* \TrackSegment connected, the intersection of the free interval
* around them in their track.
*
* It is important to note that the \TrackSegment overlaping in the
* target track is not removed from the track. It is it's perpandiculars
* which are, along with a modification of theirs left axis weight and/or
* right axis weight.
*
* Second remark: no overlap will be created (due to the non-removal of
* overlaping \TrackSegments) because the insertion is delayed in case
* of overlap.
* </ul>
* The perpandicular interval comes from perpandicular constraints on \TrackSegment
* of the <i>same</i> \c Net. The left/right axis weights comes from requests of
* <i>other</i> \c Nets.
*
* \image html RoutingEvent-1.png "RoutingEvent Intervals"
* \image latex RoutingEvent-1.pdf "RoutingEvent Intervals" width=0.6\textwidth
*
* Example of perpandicular interval computation :
*
* \image html RoutingEvent-2.png "Perpandicular Interval"
* \image latex RoutingEvent-2.pdf "Perpandicular Interval"
*
*
* \section secRoutingEventRules Rules governing RoutingEvents
*
* \RoutingEvent respect the following rules:
* <ul>
* <li>A \TrackSegment can only be displaced by it's associated \RoutingEvent.
* <li>Corollary: the only \TrackSegment displaced while processing a
* \RoutingEvent is the one associated to the event.
* <li>Conflicts occurs between the \RoutingEvent \TrackSegment and already
* placed others \TrackSegment.
*
* The conflict can be solved by displacing/modifying <i>others</i>
* \TrackSegment or by modifying the to be inserted one. In the later
* case, the newly created or modified \TrackSegment are (re)scheduleds
* <i>before</i> the would be inserted.
* <li>Conflicting \TrackSegments are only removed from their \Track
* but their axis remains unchanged. Movement requests are passed
* through increase of the left/right axis weights, if needed.
* <li>\TrackSegment are inserted only, and only if there is enough free space.
* That is, if any kind of overlap occurs, it is <i>not</i> inserted
* but <i>rescheduled</i>. The blocking \TrackSegments are then
* rescheduled <i>after</i> the current one.
* <li>Each \RoutingEvent processing takes place inside a one atomic
* Session. That is, the coherency of the data-base is restored
* immediatly afterward (both Kite &amp; Katabatic).
* </ul>
*
* \remark Be very careful to distinguish between Session commands, which affects
* \Track and \TrackSegment insertion/update/removal and schedule/re-schedule
* events, which relates to the negociation algorithm.
*
* Re-ordering rules:
* <ol>
* <li>In normal mode, that is, no maximum ripup has been reached, the
* blocking <i>other</i> \TrackSegment are removed and the current
* is rescheduled <i>before</i> them.
* <li>In maximum ripup mode, some \TrackSegment has to give way.
* <ul>
* <li>If the current one is modified, it must be rescheduled <i>after</i>
* it's modified bits are rescheduleds.
* <li>If <i>others</i> are modifieds they must be rescheduled <i>after</i>
* the current one (so it will grabs the place).
* </ul>
* </ol>
*
*
* \section secRoutingEventCycle RoutingEvent life cycle
*
* As an active \RoutingEvent is associated with one and only one \TrackSegment
* we can talk indeferently of \RoutingEvent lifecycle or \TrackSegment
* lifecycle.
*
* Below is the ordered list of states that a \RoutingEvent could be in.
* The order correspond to increasing level of slackening/freedom.
* Transition between states occurs each time a maximum ripup is reached.
*
* <table>
* <tr>
* <td align="center">&nbsp;\b Id&nbsp;</td>
* <td align="center">\b Type</td>
* <td align="center">&nbsp;\b Local&nbsp;</td>
* <td align="center">&nbsp;\b Global&nbsp;</td>
* <td align="center">\b Action</td>
* </tr>
* <tr>
* <td align="center">\e 1</td>
* <td align="center">\c Minimize</td>
* <td align="center">\e yes</td>
* <td align="center">\e no</td>
* <td>try to fit into a hole</td>
* </tr>
* <tr>
* <td align="center">\e 2</td>
* <td align="center">\c DogLeg</td>
* <td align="center">\e yes</td>
* <td align="center">\e no</td>
* <td>Dogleg : analyse overlap and try to solve it by breaking (self)</td>
* </tr>
* <tr>
* <td align="center">\e 3</td>
* <td align="center">\c Desalignate</td>
* <td align="center">\e yes</td>
* <td align="center">\e yes</td>
* <td>on a set of alignated \TrackSegment, suppress the
* alignment constraints, thus making then independants
* </td>
* </tr>
* <tr>
* <td align="center">\e 4</td>
* <td align="center">\c Slacken</td>
* <td align="center">\e yes</td>
* <td align="center">\e yes</td>
* <td>if the target/source constraint is less than the
* GCell, adds perpandicular straps to free the \TrackSegment.
* This occurs to free from terminal constraints
* </td>
* </tr>
* <tr>
* <td align="center">\e 5</td>
* <td align="center">\c ConflictSolve1</td>
* <td align="center">\e yes</td>
* <td align="center">\e yes</td>
* <td>try to find in the history a reccurent dislodger,
* and break (self) to accomodate it
* </td>
* </tr>
* <tr>
* <td align="center">\e 6</td>
* <td align="center">\c ConflictSolve2</td>
* <td align="center">\e no</td>
* <td align="center">\e yes</td>
* <td>try to find a Track on which we can dislodge
* an other \TrackSegment
* </td>
* </tr>
* <tr>
* <td align="center">\e 7</td>
* <td align="center">\c MoveUp</td>
* <td align="center">\e no</td>
* <td align="center">\e yes</td>
* <td>try to go on upper layer.
* </td>
* </tr>
* <tr>
* <td align="center">\e 8</td>
* <td align="center">\c Unimplemented</td>
* <td align="center">\e no</td>
* <td align="center">\e yes</td>
* <td>we failed to place this \TrackSegment
* </td>
* </tr>
* </table>
*
*
* \section secManageMaximumRipup Managing the maximum ripup case
*
\code
bool State::manageMaximumRipup ()
{
bool success = false;
if ( !_segment->isGlobal() ) {
// Candidates Tracks (ignore optimal & perpandiculars).
candidates = computeAllIntervals ();
overlap = _segment->getInterval();
for ( size_t i=0 ; i<candidates.size() ; i++ ) {
others = otherSegmentsConflicts(candidates[i]);
// Select Track with only one conflicting other.
if ( others.size() == 1 ) {
// Local vs. Local => reject.
// Local vs. Terminal => reject.
if ( others[0]->isLocal() || others[0]->isTerminal() ) continue;
// Local vs. Global (not routed yet).
if ( others[i]->getOrder() >= _segment->getOrder() ) {
success = modifyTopology(others[0]);
break;
}
// Local vs. Global (already routed).
success = relax(_others[0],overlap);
if ( success ) break;
}
}
}
if ( !success ) {
// Global vs. Local.
// Failed Local vs. Any.
success = modifyTopology(_segment);
}
return success;
}
\endcode
*
*
* \section secModifyTopology Description of the modifyTopology() method
*
\code
bool Manipulator::modifyTopology ( TrackSegment* segment )
{
bool success = false;
if ( segment->isLocal() ) {
if ( segment->canMinimize() {
segment->minimize();
success = true;
}
if ( segment->canDogLeg() ) {
// Case -C.4- "Self Relax".
segment->makeDogLeg();
success = true;
}
} else if ( segment->canDesalignate() ) {
// Case -C.5- "Desalignate".
segment->desalignate();
success = true;
} else if ( segment->canSlacken() ) {
// Case -C.6- "Slacken".
segment->slacken();
success = true;
} else {
RipupHistory* history = RipupHistory(segment);
GCell* dogLegGCell = history.getDogLegGCell();
if ( dogLegGCell ) {
if ( segment->canDogLegAt(dogLegGCell) ) {
segment->makeDogLeg(dogLegGCell)
success = true;
}
} else {
// Dislodgers seems to far in ripup history.
// Recheck the Track, maybe they have vanish.
Track* track = getTrack(segment);
if ( track->getFreeInterval(segment) ) {
track.insert ( segment );
success = true;
}
}
}
if ( segment->canMoveUp() ) {
segment->moveUp ();
success = true;
}
if ( success ) {
resetRipupCount(segment);
} else {
cerr << "[UNIMPLEMENTED] " << segment << endl;
}
return success;
}
\endcode
*
*
* \section secHardSoftOverlap Hard and soft overlap
*
* Schematic execution of a \RoutingEvent leading to a set aside.
* <ol>
* <li>The scheduler try to place the \TrackSegment on top of the
* event queue, calling process().
* <li>There is a soft overlap on the best candidate track, a set
* aside is issued.
* <li>Each \TrackSegment in conflict in the candidate track has the
* \RoutingEvent bounds of it's perpandicular \TrackSegment modificated
* according to the free space requested through setLeftBound() or setRightBound().
* <li>If a perpandicular is already in a \Track is removed from it and scheduled for
* immediate re-routing (it's event level is increased so it pops
* out immediately from the queue).
* <li>If the perpandicular is not routed yet, we are done.
*
* Note that this technique of modificating a \RoutingEvent yet to come is
* kind a like seeing the future...
* </ol>
*
* \image html RoutingEvent-3.png "Set aside schematic"
* \image latex RoutingEvent-3.pdf "Set aside schematic"
*
*
* \section setDetructionStrategy Destruction Strategy
*
* \RoutingEvent are not destroyed as soon as they have been processed by
* the scheduler. Instead, they are stored in the historical queue.
* They are two reasons for that behavior :
* <ul>
* <li>\RoutingEvent are used to store algorithmic informations that
* must persist until the negociation algorithm have fully
* completed (<i>bound</i> interval in particular).
* <li>When ripup phases takes place and maximum ripup count is
* reached, the history can be used to find the whole set of
* \TrackSegment in conflict an made an educated guess about
* which one must be relaxed.
* </ul>
*
* \important This is the history queue which is responsible for freeing all the
* \RoutingEvent in his destructor.
*
*
* \section secRoutingEventCase Routing Event actions
*
* <ul>
* <li><b>Free Track Case</b>
*
* There is a sufficent free space in the candidate \Track to insert the
* \TrackSegment. The \TrackSegment is inserted.
*
* \important This is the only way for a \TrackSegment to be inserted into a \Track.
*
* \image html RoutingEvent-10.png
* \image latex RoutingEvent-10.pdf
*
*
* <li><b>Soft Overlap Case</b>
*
* Already inserted \TrackSegment <b>a</b> &amp; <b>b</b> could be shrunk
* to make place for \TrackSegment <b>c</b>. Parallel overlaping \TrackSegment
* are not removed, their perpandiculars are with updated left/right axis weight.
*
* The <b>a</b> perpandicular belongs the same GCell routing set so it
* is removed from is \Track to be displaced.
*
* The <b>b</b> perdandicular belongs to a more prioritary GCell routing
* set, which has therefore be placed earlier so it can't be removed.
* Instead it is broken.
*
* \image html RoutingEvent-11.png
* \image latex RoutingEvent-11.pdf
*
*
* <li><b>Hard Overlap Case</b>
*
* No way to shrunk overlaping \TrackSegment to make place for <b>c</b>.
* All parallel overlaping \TrackSegments must be removeds to be displaced
* on other \Tracks.
*
* The <b>a</b> parallel belongs to a more prioritary GCell routing set
* so it can be removed, it is therefore broken.
*
* The <b>b</b> parallel belongs the same GCell routing set so it can be
* removed to be displaced.
*
* \image html RoutingEvent-12.png
* \image latex RoutingEvent-12.pdf
*
*
* <li><b>Self Relax</b>
*
* Instead of trying to displace overlaping \TrackSegments we break the
* current one.
*
* \image html RoutingEvent-13.png
* \image latex RoutingEvent-13.pdf
*
*
* <li><b>Self Desalignate</b>
*
* Instead of trying to displace overlaping \TrackSegments we desalignate
* it's components (by supressing alignement constraints on it's
* AutoContacts). We do not create new Katabatic components but new
* \TrackSegments will appears.
*
* \image html RoutingEvent-14.png
* \image latex RoutingEvent-14.pdf
*
*
* <li><b>Self Slacken</b>
*
* Instead of trying to displace overlaping \TrackSegments we slacken
* the current one. This is different than desalignate because we create
* new Katabatic component to relax any AutoContact transmitted constraints.
* This operation is most likely to be applied on \TrackSegments that are
* directly connecteds to terminals.
*
* \image html RoutingEvent-15.png
* \image latex RoutingEvent-15.pdf
*
* </ul>
*/
/*! \function bool RoutingEvent::isProcessed () const;
* \return \true if this event has already been processed.
*
* \remark Note that inside a _setAside() a \RoutingEvent can be re-posted for
* a given \TrackSegment which has been processed yet. This can lead
* to two or more \RoutingEvent in the queue (as we cannot easily remove
* a \RoutingEvent already in the queue). We need this new \RoutingEvent
* because we want to reschedule with a new priority/slack.
* As we cannot remove the previous \RoutingEvent, we mark it as
* processed for it to be ignored by the scheduler.
*/
/*! \function TrackSegment* RoutingEvent::getSegment () const;
* \Return The associated and unique \TrackSegment.
*/
/*! \function unsigned long RoutingEvent::getPriority () const;
* \Return The second criterion used to sort \RoutingEvents in the negociation queue.
* Currently, it is the <i>area</i> of the associated \TrackSegment, which in
* turn return the <i>slack</i> (not a very fortunate choice of name...).
*/
/*! \function unsigned int RoutingEvent::getEventLevel () const;
* \Return The first criterion used to sort \RoutingEvents in the negociation queue.
* It is used to re-schedule a \RoutingEvent and make the new event be
* processed <i>before</i> the original one, which is marked as
* <i>processed</i> to be ignored.
*
* \see setEventLevel().
*/
/*! \function RoutingEvent* RoutingEvent::getClone () const;
* \Return An exact copy of the current \RoutingEvent.
*/
/*! \function RoutingEvent* RoutingEvent::reschedule ( RoutingEventQueue& queue );
* \param queue The \RoutingEvent queue.
* \return The rescheduled \RoutingEvent. May be \NULL if it cannot be rescheduled.
*/
/*! \function void RoutingEvent::setProcessed ( bool state=true );
* \param state The state into which the event is to be put.
*
* Mark the event as processed. This arises in two cases :
* <ul>
* <li>The event has really been processed by the process() member
* function.
* <li>There has been a fork from this event and it has been
* superseded by a newly rescheduled one, so we have to
* invalidate this one.
* </ul>
*/
/*! \function void RoutingEvent::setEventLevel ( unsigned int level );
* \param level The new event level.
*
* \see getEventLevel().
*/
/*! \function void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history );
* \param queue The event queue from the negociate algorithm.
* \param history The event history.
*
* Perform all the operations shared by all \RoutingEvent classes then
* calls the virtual _subProcess() functions.
*
* Shared operations are :
* <ol>
* <li>Invalidating all perpandicular \TrackSegments.
* <li>Computing the free interval allowed by the free intervals
* in perpandicular \Tracks holding the perpandicular \TrackSegments.
* <li>Merging in the various constraints intervals : from the
* \TrackSegment itself, from the free intervals in the
* perpandicular \Tracks and from the \RoutingEvent bound
* constraints.
* <li>Finding the candidate \Tracks for the \RoutingEvent,
* using \c Track_Spiral \Collection.
* </ol>
* The results of the shared operation are passed to derived classes
* trough the \c State internal structure.
*/
/* \function bool RoutingEvent::_setAside ( Track* track, size_t begin, size_t end, Net* net, Interval interval, RoutingEventQueue& queue );
* \param track The track in wich to make free space.
* \param begin The index of the first overlaping TrackSegment.
* \param end The index of the last overlaping TrackSegment.
* \param net The net for which we want to insert a TrackSegment.
* \param interval The interval which must be made empty.
* \param queue The queue of RoutingEvent.
*
* Manage the case of <i>soft overlap</i>. Create or enlarge a free space
* in \c track so it can contain the requested \interval. <code>[begin:end]</code> defines
* the range of indexes of overlaping \TrackSegment in \c track.
* Displace TrackSegment that are <b>perpandicular</b> to those overlaping,
* remove them from their \c Track if needed and issue an associated \RoutingEvent
* with an updated bound constraint. Note that the overlaping \TrackSegment
* themselves are <em>not</em> removed from the \c track.
*
* A note on implementation :
* <ul>
* <li>\c data1 : the DataNegociate of the to be inserted \TrackSegment.
* <li>\c segment2 : the current overlaping \TrackSegment (from \c begin
* to \c end).
* <li>\c data2 : the DataNegociate of the overlaping \TrackSegment.
* <li>\c segment3 : a \TrackSegment perpandicular to \c segment2.
* </ul>
*/
/* \function void RoutingEvent::_ripup ( Track* track, Net* net, Interval interval, size_t begin, size_t end, RoutingEventQueue& queue );
* \param track The track in wich to make free space.
* \param net The net for which we want to insert a TrackSegment.
* \param interval The interval which must be made empty.
* \param begin The index of the first overlaping TrackSegment.
* \param end The index of the last overlaping TrackSegment.
* \param queue The queue of RoutingEvent.
*
* Manage the case of <i>hard overlap</i>, that is bluntly remove
* any \TrackSegment overlaping \interval. Issue both a remove event
* (to \c Session) and a \RoutingEvent to re-process the dislodged
* \TrackSegment.
*/
} // End of Kite namespace.