// -*- 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 *
  • New \c isLocal() method on \TrackSegment. Tells if the \TrackSegment * is associated only to local AutoSegment. *
  • Increase the overlap cost of a \TrackSegment from an already routed * GCell routing set. * * * * \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. * * The perpandicular interval comes from perpandicular constraints on \TrackSegment * of the same \c Net. The left/right axis weights comes from requests of * other \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: * * * \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: *
      *
    1. In normal mode, that is, no maximum ripup has been reached, the * blocking other \TrackSegment are removed and the current * is rescheduled before them. *
    2. In maximum ripup mode, some \TrackSegment has to give way. *
        *
      • If the current one is modified, it must be rescheduled after * it's modified bits are rescheduleds. *
      • If others are modifieds they must be rescheduled after * the current one (so it will grabs the place). *
      *
    * * * \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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     \b Id \b Type \b Local  \b Global \b Action
    \e 1\c Minimize\e yes\e notry to fit into a hole
    \e 2\c DogLeg\e yes\e noDogleg : analyse overlap and try to solve it by breaking (self)
    \e 3\c Desalignate\e yes\e yeson a set of alignated \TrackSegment, suppress the * alignment constraints, thus making then independants *
    \e 4\c Slacken\e yes\e yesif the target/source constraint is less than the * GCell, adds perpandicular straps to free the \TrackSegment. * This occurs to free from terminal constraints *
    \e 5\c ConflictSolve1\e yes\e yestry to find in the history a reccurent dislodger, * and break (self) to accomodate it *
    \e 6\c ConflictSolve2\e no\e yestry to find a Track on which we can dislodge * an other \TrackSegment *
    \e 7\c MoveUp\e no\e yestry to go on upper layer. *
    \e 8\c Unimplemented\e no\e yeswe failed to place this \TrackSegment *
    * * * \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 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. *
      *
    1. The scheduler try to place the \TrackSegment on top of the * event queue, calling process(). *
    2. There is a soft overlap on the best candidate track, a set * aside is issued. *
    3. 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(). *
    4. 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). *
    5. 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... *
    * * \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 : *
      *
    • \RoutingEvent are used to store algorithmic informations that * must persist until the negociation algorithm have fully * completed (bound interval in particular). *
    • 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. *
    * * \important This is the history queue which is responsible for freeing all the * \RoutingEvent in his destructor. * * * \section secRoutingEventCase Routing Event actions * *
      *
    • Free Track Case * * 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 * * *
    • Soft Overlap Case * * Already inserted \TrackSegment a & b could be shrunk * to make place for \TrackSegment c. Parallel overlaping \TrackSegment * are not removed, their perpandiculars are with updated left/right axis weight. * * The a perpandicular belongs the same GCell routing set so it * is removed from is \Track to be displaced. * * The 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 * * *
    • Hard Overlap Case * * No way to shrunk overlaping \TrackSegment to make place for c. * All parallel overlaping \TrackSegments must be removeds to be displaced * on other \Tracks. * * The a parallel belongs to a more prioritary GCell routing set * so it can be removed, it is therefore broken. * * The 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 * * *
    • Self Relax * * Instead of trying to displace overlaping \TrackSegments we break the * current one. * * \image html RoutingEvent-13.png * \image latex RoutingEvent-13.pdf * * *
    • Self Desalignate * * 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 * * *
    • Self Slacken * * 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 * *
    */ /*! \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 area of the associated \TrackSegment, which in * turn return the slack (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 before the original one, which is marked as * processed 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 : *
      *
    • The event has really been processed by the process() member * function. *
    • 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. *
    */ /*! \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 : *
      *
    1. Invalidating all perpandicular \TrackSegments. *
    2. Computing the free interval allowed by the free intervals * in perpandicular \Tracks holding the perpandicular \TrackSegments. *
    3. Merging in the various constraints intervals : from the * \TrackSegment itself, from the free intervals in the * perpandicular \Tracks and from the \RoutingEvent bound * constraints. *
    4. Finding the candidate \Tracks for the \RoutingEvent, * using \c Track_Spiral \Collection. *
    * 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 soft overlap. Create or enlarge a free space * in \c track so it can contain the requested \interval. [begin:end] defines * the range of indexes of overlaping \TrackSegment in \c track. * Displace TrackSegment that are perpandicular 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 not removed from the \c track. * * A note on implementation : *
      *
    • \c data1 : the DataNegociate of the to be inserted \TrackSegment. *
    • \c segment2 : the current overlaping \TrackSegment (from \c begin * to \c end). *
    • \c data2 : the DataNegociate of the overlaping \TrackSegment. *
    • \c segment3 : a \TrackSegment perpandicular to \c segment2. *
    */ /* \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 hard overlap, 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.