Forgotten doc files.

This commit is contained in:
Jean-Paul Chaput 2013-12-04 02:51:02 +00:00
parent 9965b34e9b
commit f2192ae3bd
21 changed files with 4217 additions and 0 deletions

36
kite/doc/Constants.dox Normal file
View File

@ -0,0 +1,36 @@
// -*- mode: C++; explicit-buffer-name: "Constants.h<kite/doc>" -*-
namespace Kite {
//! \enum FunctionFlag
//! A set of flags to that can be passed to functions/methods througout
//! all Kite.
//! \var KtLoadGlobalRouting
//! Reload the global routing from a preciously saved run (\c .kgr file).
//! \var KtBuildGlobalRouting
//! Run the global router Knik.
//! \var KtAllowDoglegReuse
//! Allow sharing of dogleg.
//! \var KtDataSelf
//! \red{To be documented.}
//! \var KtNearest
//! Round the position to the nearest track axis.
//! \var KtForce
//! Force to perform an action ignoring the "up to date" state.
//! \var KtResetCount
//! Tells to reset a counter.
//! \var KtWithPerpands
//! Ripup perpandiculars alongside the current segment.
//! \var KtWithConstraints
//! Force constraints recomputation.
}

217
kite/doc/DataNegociate.dox Normal file
View File

@ -0,0 +1,217 @@
// -*- C++ -*-
namespace Kite {
/*! \class DataNegociate
* \brief Algorimthmic datas associated the TrackSegment
*
* The DataNegociate object contains all the informations the negociation
* algorithm needs to know about a TrackSegment. Those informations
* mostly describe the slackening and ripup state of that segment.
*
* <b>State related datas:</b>
* - The ripup count in the current state. The count is reset
* to zero at each state transition.
* - The slackening state (see DataNegociate::SlackState). The state
* indicate the \b next topological modification to be applied on
* the segment should the ripup count reach it's maximal value.
* - The associated RoutingEvent. If no RoutingEvent is present, it
* means the segment has been either successufully placed or the
* algorithm has given up trying to. If present, it is a \e pending
* request for placement.
*
* <b>Topological related datas:</b>
* - \c leftMinExtend, the potential minimal position of the segment
* left extension. May not be reachable due to other topological
* constraints.
* - \c rightMinExtend, the potential minimal position of the segment
* right extension.
* - \c terminals, the number of terminals attached to this segment.
* - \c attractors, a table of coordinates of the end points of the
* perpandiculars to this segment. Used to compute the wiring delta
* if we move the axis of the segment.
* - \c perpandiculars, a \c vector of the perpandicular TrackElement.
* This is a fast-access cache. It must be updated each time the
* topology of the net is modificated.
* - \c perpandicularFree, the free interval defined by the perpandiculars,
* that is for the sgement axis.
*
*
* \section secAttractorsComputation Perpandiculars, Free, Attractors & Wiring Delta
*
* All those informations are computed and updated by the
* DataNegociate::update() method, which relies on:
* - AutoSegment::getTopologicalInfos()
* - AutoSegment::getTerminalCount()
*
* \red{They must be reviewed as they do not take advantage of the new}
* \red{AutoSegment structuration.}
*
* For every perpandicular set of AutoSegment to the TrackSegment
* we want to place, get the coordinates of the extremity not connected
* to the segment and put that coordinate into a table associated with
* it's \e spin. The \e spin tells if the extremity is attracting the
* segment \e up or \e down (for an horizontal segment). The \e spin
* is incremented for up and decremented for down. After all the
* extremities have been processeds, we took into account only the
* coordinates with a non-zero spin, which means they truly attract
* the segment (whatever the direction).
*
* \image html DataNegociate-1.png "Fig 1: Attractors Computation"
*
* The <em>wiring delta</em> is the total wire length needed to connect
* from the attractors to the segment, should it be placed on \c axis.
*
* \image html DataNegociate-2.png "Fig 2: Wiring Delta"
*
*
* \section secDataNegociateModifications Modifications History
*
* Main changes in DataNegociate class design:
* - Merge in the separate class \c Cost.
* - Suppress the \c SlackState::Desalignate, due to the simplificated
* structure of the AutoSegment/AutoContacts (no more collapseds, or
* forced alignements).
*/
//! \enum DataNegociate::SlackState
//! Describe the various stages of a TrackSegment slackening.
//! The numerical values are choosen so we can increment them
//! as a counter.
//! \var DataNegociate::RipupPerpandiculars
//! Force perpandiculars to be riped up as well as the TrackSegment,
//! then schedule the placement of the TrackSegment \e before it's perpandiculars.
// \var DataNegociate::Desalignate
//! If the TrackSegment is made of multiple TrackSegments with a forced
//! alignement, suppress the alignement constraint.
//!
//! \red{This should be deprecated now}.
//! \var DataNegociate::Minimize
//! Try to displace the perpandiculars so the TrackSegment is
//! reduced to it's minimal length.
//! \var DataNegociate::Dogleg
//! Break the segment into two smaller ones.
//! \var DataNegociate::Slacken
//! Create additional wiring so threre is no more contraints transmitted
//! by the perpandiculars or the terminal contacts.
//! \var DataNegociate::ConflictSolveByHistory
//! Try to solve a conflict between a set of global segments by
//! analysing the event/ripup history. See SegmentFsm::conflictSolveByHistory().
//! \var DataNegociate::ConflictSolveByPlaceds
//! Try to solve a conflict between a set of global segments by
//! analysing the current track context. See SegmentFsm::conflictSolveByPlaceds().
//! \var DataNegociate::LocalVsGlobal
//! \red{To be reviewed}.
//! \var DataNegociate::MoveUp
//! The segment is to be moved up (if possible).
//! \var DataNegociate::MaximumSlack
//! The final state, topological modifications are exhausteds, if it
//! cannot place at this point, it never will.
//! \var DataNegociate::Unimplemented
//! Used only during the development stage, telling that the state is
//! not available yet.
//! \var DataNegociate::Repair
//! The router is in repair mode.
//! \function bool DataNegociate::hasRoutingEvent () const;
//! \sreturn \true if there is a pending RoutingEvent for this TrackSegment.
//! \function RoutingEvent* DataNegociate::getRoutingEvent () const;
//! \sreturn The pending RoutingEvent. \c NULL will be returned if there is no
//! pending event, meaning that the segment has been placed.
//! \function TrackSegment* DataNegociate::getTrackSegment () const;
//! \sreturn The associated TrackSegment.
//! \function Track* DataNegociate::getTrack () const;
//! \sreturn A proxy accessor for the segment's track.
//! \function DbU::Unit DataNegociate::getLeftMinExtend () const;
//! \sreturn The minimum extend possible of the segment's source (left) ending.
//! Computed by DataNegociate::update().
//! \function DbU::Unit DataNegociate::getRightMinExtend () const;
//! \sreturn The minimum extend possible of the segment's target (right) ending.
//! Computed by DataNegociate::update().
//! \function unsigned int DataNegociate::getTerminals () const;
//! \sreturn The number of terminal to which this segment is connected
//! Computed by DataNegociate::update().
//!
//! \red{Must be refined: direct or indirect?}.
//! \function Net* DataNegociate::getNet () const;
//! \sreturn A cached accessor to the segment's net (for faster access).
//! \function unsigned int DataNegociate::getState () const;
//! \sreturn The current state (see DataNegociate::SlackState).
//! \function unsigned int DataNegociate::getStateCount () const;
//! \sreturn The number of times we have reached the ripup limit while in
//! this stage.
//! \function unsigned int DataNegociate::getRipupCount () const;
//! \sreturn The number of times the segment has been riped up in this stage.
//! \function unsigned int DataNegociate::getStateAndRipupCount () const;
//! \return A composite number combining the state and the ripup count:
//! <code>(state<<4)+ripup</code>.
//! \function DbU::Unit DataNegociate::getWiringDelta ( DbU::Unit axis ) const;
//! \sreturn The wiring length needed to connect to the attractors if the segment
//! is put on \c axis. The lower, the better...
//! \function const Interval& DataNegociate::getPerpandicularFree () const;
//! \sreturn The range of legal positions generated only by the perpandiculars.
//! \function void DataNegociate::setState ( unsigned int state, unsigned int flags=0 );
//! Set or reset the slacking state (see SlackState). If the \c state is the
//! same as the current one, the state count is incremented. If the new state
//! changes or \c flags contain KtReset, the state count is reset to one.
//! \function void DataNegociate::setRoutingEvent ( RoutingEvent* event );
//! Associate \c event to this TrackSegment.
//! \function void DataNegociate::setRipupCount ( unsigned int count );
//! Directly sets the ripup count to \c count.
//! \function void DataNegociate::incRipupCount ();
//! Increment the ripup count. No check is performed for bound limit.
//! \function void DataNegociate::decRipupCount ();
//! Decrement the ripup count (will never go below zero).
//! \function void DataNegociate::resetRipupCount ();
//! Reset the ripup count to zero.
//! \function void DataNegociate::resetStateCount ();
//! Reset the state count to zero.
// \function void DataNegociate::invalidate ( unsigned int flags=0 );
// Invalidate the associated RoutingEvent.
//
// Possible values for \c flags :
// - Kite::KtWithPerpands
// - Kite::KtWithConstraints
//! \function void DataNegociate::update ();
//! Recompute \c leftMinExtend, \c righMinExtend, number of terminals and
//! attractors positions.
//!
//! \remark The constructor do not calls it. It is to the algorithm responsability
//! to call it before using the computed datas.
}

View File

@ -0,0 +1,22 @@
// -*- C++ -*-
namespace Kite {
/*! \class HorizontalTrack
* \brief Horizontal track managment.
*/
//! \function bool HorizontalTrack::isHorizontal () const;
//! \sreturn \true.
//! \function bool HorizontalTrack::isVertical () const;
//! \sreturn \false.
//! \function unsigned int HorizontalTrack::getDirection () const;
//! \sreturn Katabatic::KbHorizontal.
//! \function Point HorizontalTrack::getPosition ( DbU::Unit position ) const;
//! \sreturn the point at \c (position,getAxis()).
}

55
kite/doc/KiteEngine.dox Normal file
View File

@ -0,0 +1,55 @@
// -*- C++ -*-
namespace Kite {
/*! \class KiteEngine
*
* \brief The Kite Tool
*
* <b>Lookup Mechanism</b>
*
* Please look at Kite::Session for an explanation of the lookup
* mechanism from Hurricane::Segment or Katabatic::AutoSegment to
* TrackSegment.
*/
//! \function const Name& KiteEngine::staticGetName ();
//! \sreturn The unique string identifier for the KiteEngine class of ToolEngine.
//! \function KiteEngine* KiteEngine::create ( Cell* cell );
//! Create a KiteEngine on \c cell.
//! \function KiteEngine* KiteEngine::get ( const Cell* cell );
//! \sreturn The KiteEngine associated to \c cell. \c NULL if there isn't.
//! \function KatabaticEngine* KiteEngine::base ();
//! \sreturn The KiteEngine, casted as it's base class (KatabaticEngine).
//! \function Configuration* KiteEngine::getKiteConfiguration ();
//! \sreturn The KiteEngine configuration. The Kite Configuration is a derived
//! class of KatabaticConfiguration.
//! \function Configuration* KiteEngine::getConfiguration ();
//! \sreturn The KiteEngine configuration.
//! \function Net* KiteEngine::getBlockageNet ();
//! \sreturn The Net which is used to mark the blockage segments. It's not part of
//! the Configuration <em>per se</em> but an isolated attribute.
//! \function bool KiteEngine::getToolSuccess () const;
//! \sreturn \true if the tool was successful, that is, all the Net were routeds.
//! \function unsigned long KiteEngine::getEventsLimit () const;
//! \sreturn The maximal number of allowed routing events. This limit is a security
//! against infinite looping, be sure that it is great enough not to
//! prevent normal routing completion.
//! \function unsigned long KiteEngine::getRipupLimit ( unsigned int type ) const;
//! \sreturn the maximum ripup allowed of a segment of \c type.
//! \function unsigned long KiteEngine::getRipupCost () const;
//! \sreturn the differential used while comparing two ripup costs.
}

266
kite/doc/Manipulator.dox Normal file
View File

@ -0,0 +1,266 @@
// -*- C++ -*-
namespace Kite {
/*! \class Manipulator
* \brief Handle TrackElement ripup & topological modifications.
*
* \section secManipStruct Manipulator Structure
*
* A Manipulator basically binds together a TrackElement, it's
* DataNegociate and RoutingEvent (cached for fast access), and
* \b a SegmentFsm.
*
* <em>The TrackElement may differs from the one of the SegmentFsm.</em>
* This can occurs when manipulating perpandiculars or segments from
* other nets in conflict. For example: Manipulator::isCaged().
*
* In the following documentation, the segment <em>which is associated
* to the SegmentFsm</em> will be called the <em>reference segment</em>.
*
* \section secManipDelayed Delayed Modifications
*
* It is important to note that when a Manipulator is called to
* modificate a TrackElement, nothing is actually done by the
* Manipulator itself. Instead, the Manipulator create the
* relevant SegmentAction (s) that are stored in the SegmentFsm.
* The action themselves are done at the end of the SegmentFsm
* lifecycle (wrapped inside a Session).
*
* \red{This is not true!} When dogleg are created, the topology is
* immediatly modificated. That way of doing must be clarified.
*/
//! \enum Manipulator::FunctionFlag
//! The various flags that can be passed to the Manipulator methods.
//! \var Manipulator::ToRipupLimit
//! The ripup limit must be immediatly to it's limit for the current
//! state.
//! \var Manipulator::AllowExpand
//! Allow break points for dogleg not to be exactly on the requested
//! position. Meaning that they are moved to the least congested
//! GCell.
//! \var Manipulator::NoExpand
//! Breakpoints for dogleg are kept right where they are requested.
//! \var Manipulator::PerpandicularsFirst
//! Reorder the events so that perpandiculars segments are re-processed
//! before their reference segment. By default this is the other way
//! around.
//! \var Manipulator::ToMoveUp
//! Try to move up ripped up segments.
//! \var Manipulator::AllowLocalMoveUp
//! Allow local segments to be moved up (forbidden by default).
//! \var Manipulator::AllowTerminalMoveUp
//! Allow terminal segments to be moved up (forbidden by default).
//! \var Manipulator::AllowShortPivotUp
//! Allow short segment yo be pivoted up.
//! \var Manipulator::NoDoglegReuse
//! When creating a dogleg, the default behavior is \e not to create a
//! new one if there's already one in the same GCell. If this flag is
//! set, a second dogleg will be created.
//! \var Manipulator::RightAxisHint
//! An explicit right axis hint has been supplied as argument.
//! \var Manipulator::LeftAxisHint
//! An explicit left axis hint has been supplied as argument.
//! \var Manipulator::NotOnLastRipup
//! The reference segment has still more than one ripup to go for
//! the given state.
//! \function Manipulator::Manipulator ( TrackElement* segment, SegmentFsm& fsm );
//! \param segment The TrackElement to manipulate.
//! \param fsm The associated SegmentFsm.
//!
//! Construct a new Manipulator on \c segment.
//! \function TrackElement* Manipulator::getSegment () const;
//! \sreturn The working TrackElement.
//! \function DataNegociate* Manipulator::getData () const;
//! \sreturn The DataNegociate of the TrackElement (act as a cache).
//! \function RoutingEvent* Manipulator::getEvent () const;
//! \sreturn The RoutingEvent associated to the TrackElement (act as a cache).
//! \function bool Manipulator::canRipup ( unsigned int flags ) const;
//! \sreturn \true if the maximum ripup, for the given SegmentFsm::State has not
//! been reached. If \c flags contains Manipulator::HasNextRipup, return
//! \true \b only if it still have at least one ripup to go.
//! \function bool Manipulator::isCaged ( DbU::Unit axis ) const;
//! \sreturn \true if the segment is enclosed (in it's Track) by two fixed or
//! blockage segments which at least one is closer than 10 lambdas from
//! \c axis. Mostly used to know if a perpandicular is actually restricting
//! the axis span of a reference segment.
//! \function bool Manipulator::ripup ( unsigned int type, DbU::Unit axisHint=0 );
//! \param type The type of ripup action.
//! \param axisHint An indication as where to move the riped up segment.
//! \return \true if the operation has succedeed.
//!
//! If the TrackElement can be ripped up, schedule a ripup action, possibly
//! with a hint for the preferred axis position.
//! \function bool Manipulator::ripupPerpandiculars ( unsigned int flags );
//! Schedule a ripup of all the perpandiculars of the reference segment.
//! \c flags that modificate the behavior:
//! - Manipulator::PerpandicularsFirst : the queue will be reordered so
//! that all the perpandiculars are re-processed (placed) before the
//! reference segment.
//! - Manipulator::ToRipupLimit : the ripup count of the reference segment
//! is set to the limit (i.e. only one more attempt before a slackening
//! occurs).
//!
//! The method will fails (return \false) if at least one perpandicular can't
//! be changed of track (i.e. ripped up) \b and none of it's neighbors could
//! be ripped up either. Meaning that the free span on that track cannot be
//! changed.
//! \function void Manipulator::repackPerpandiculars ();
//! Ripup all the perpandiculars of the reference segment, except fixed or
//! globals. The reference segment is rescheduled first (before it's
//! perpandicular).
//!
//! This function may be used to find a better placement, maximizing the
//! overlap of the various perpandiculars.
//! \function bool Manipulator::ripple ();
//! \sreturn true if the reference segment is local.
//!
//! Applies only on reference segments that are of local type.
//! Tries to make room for the reference segment by ripping up it's neigbors
//! on the parallels tracks. On a vertical plane, left neigbors are shifted
//! one track left (trough axis hint) and right ones, one track right.
//! Note that they are ripped up and the shift is just a hint, there's no
//! guarantee that the router can honor it.
//! \function bool Manipulator::minimize ();
//! \sreturn true if the reference segment can be mimized in a suitable track hole.
//!
//! Compute the miminal span of the reference segment, summing up contraints
//! from source anchor and target anchors (if any) and perpandiculars.
//! Then find holes in the avalaible tracks, and check if one is suitable
//! for the miminized segment (try first the biggest hole).
//!
//! This operation can only be called once on a segment (a flag is set in the
//! event).
//! \function bool Manipulator::slacken ( unsigned int flags=KbNoFlags );
//! Simple proxy towards TrackElement::slacken().
//!
//! \red{To be reviewed.}
//! \function bool Manipulator::pivotUp ();
//! Tries to move up the reference segment. The segment will be moved
//! up only if a half track is free (for a local) or a full track is
//! free (for a global).
//!
//! This function do not modifies/create perpandiculars.
//! \function bool Manipulator::pivotDown ();
//! Tries to move down the reference segment. The segment will be moved
//! up only if \e two track are free (whether global or local). Is is more
//! restrictive than Manipulator::pivotUp().
//!
//! This function do not modifies/create perpandiculars.
//! \function bool Manipulator::moveUp ( unsigned int flags );
//! Tries to move up a segment, if there is enough space in the RoutingPlane
//! above and in the same direction.
//!
//! This function may modificate perpandiculars in order to maintain
//! connexity.
//!
//! \red{To be reviewed.}
//! \function bool Manipulator::makeDogleg ();
//! \sreturn \false if the segment is \e not local or the dogleg cannot be done.
//!
//! For \e local reference segment only, look in the first track candidate
//! for other segment overlapping and break the reference accordingly.
//! \function bool Manipulator::makeDogleg ( Interval overlap );
//! Create a dogleg to avoid the obstructed interval \c overlap.
//! \function bool Manipulator::makeDogleg ( DbU::Unit position );
//! Create a dogleg in the GCell under \c position.
//! \function bool Manipulator::relax ( Interval overlap, unsigned int flags=AllowExpand );
//! Break the reference segment so it can detour around the interval
//! \c overlap. If \c overlap is completly enclosed inside the span of
//! the reference segment two dogleg will be created. If the overlap occurs
//! only on one side of the reference segment, only one dogleg will be
//! created.
//!
//! If \c flags contains Manipulator::AllowExpand, the dogleg are not created
//! exactly at the edges of the overlap but on the lowest density GCell
//! (outside the overlap interval).
//!
//! The axis of the created dogleg are sets so that the broken part of the
//! segment completly enclose \c overlap. That is, the orignal segment no
//! longer intersect with \c overlap. So the min dogleg is pushed to the
//! left and the max to the right if they are in the same GCell as the
//! min/max of \c overlap. Otherwise (they have been expanded), they are
//! put in the center of the GCell.
//!
//! We do not allow to dogleg twice in the same GCell, so if min or max
//! is in respectively the first or last GCell, it is not done. Moreover
//! if there is only one dogleg \e and it is in the first or last GCell,
//! the relax method is cancelled (and returns \false). It means that
//! this is the segment which is likely to be enclosed inside \c overlap.
//!
//! \redB{Important:} The doglegs are created immediatly and not in a delayed
//! fashion like the SegmentAction.
//!
//! \image html ManipulatorRelax-1.png "Two Doglegs (min & max), no expansion"
//! \image html ManipulatorRelax-2.png "Two Doglegs (min & max), with expansion"
//! \image html ManipulatorRelax-3.png "One Dogleg (min)"
//! \image html ManipulatorRelax-4.png "One Dogleg (max)"
//! \function bool Manipulator::insertInTrack ( size_t i );
//! Try to insert the reference segment in the track at index \c i (in the cost
//! table from SegmentFsm). The insertion is done by ripping up overlapping
//! segment or shrinking them to left/right if possible.
//!
//! \red{This operation ripup the processed segment neighbors (and their perpandiculars).}
//! \function bool Manipulator::forceToTrack ( size_t i );
//! Try to insert the reference segment in the track at index \c i (in the cost
//! table from SegmentFsm). The insertion is done by \e forcibly ripping up the
//! overlapping segments \b and their perpandiculars.
//!
//! \red{This operation ripup the processed segment neighbors (and their perpandiculars).}
//! \function bool Manipulator::shrinkToTrack ( size_t i, unsigned int flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint );
//! Attempt to minimize the reference segment to fit into the track.
//! For this operation to succeed, the minimal span of the segment must
//! not overlap any other segment already in the track. To reach the
//! minimal span the perpandiculars are ripped up with an axis hint
//! which is the center of the minimal span or the explicit value given
//! as arguments \c leftAxisHint and \c rightAxisHint if \c flags contains
//! respectively Manipulator::LeftAxisHint or Manipulator::RightAxisHint.
//!
//! \red{This operation ripup the processed segment itself and its perpandiculars.}
//! \function bool Manipulator::forceOverLocals ();
//! Loop over all the candidate tracks and, insert in the first which
//! all conflicting segments are locals (rip them up).
//! \function bool Manipulator::repackPerpandiculars ();
//! Ripup all perpandiculars and the reference segment itself for a complete
//! re-placement. The reference segment will be reprocessed \e before it's
//! perpandiculars.
}

View File

@ -0,0 +1,96 @@
// -*- C++ -*-
namespace Kite {
/*! \class NegociateWindow
* \brief Perform the routing, main RoutingEvent manager.
*
* This object perform the routing. That is creates all the
* initial RoutingEvent, load them into the queue and then
* process the queue until it is empty, that is, the routing
* is finished.
*
* This object is the owner of the RoutingEventQueue,
* RoutingEventHistory and RoutingEventLoop used all troughout
* RoutingEvent and SegmentFsm.
*/
//! \enum NegociateWindow::Stage
//! The state under which the router is operating.
//! \var NegociateWindow::Negociation
//! The normal mode, priority negociation with ripup.
//! \var NegociateWindow::Packing
//! Try to find a better placement for segment but just by
//! looking for other fully free spaces. No ripup is performed.
//! \function NegociateWindow::create ( KiteEngine* kite );
//! The publicly avalaible contructor. Route the whole are defined
//! by the Kite associated Cell abutment box.
//! \function void NegociateWindow::destroy ();
//! The publicly avalaible destructor.
//! \function bool NegociateWindow::isInterrupted () const;
//! \sreturn \true if the NegociateWindow has received an interrupt request.
//! \function KiteEngine* NegociateWindow::getKiteEngine () const;
//! \sreturn The associated KiteEngine.
//! \function Hurricane::Cell* NegociateWindow::getCell () const;
//! \sreturn The associated Cell.
//! \function const Katabatic::GCellVector& NegociateWindow::getGCells () const;
//! \sreturn A Copy of the vector of GCell from KatabaticEngine. The vector
//! is copied but not the GCell themselves (shallow copy).
//! \function RoutingEventQueue& NegociateWindow::getEventQueue ();
//! \sreturn The RoutingEventQueue.
//! \function RoutingEventHistory& NegociateWindow::getEventHistory ();
//! \sreturn The RoutingEventHistory.
//! \function RoutingEventLoop& NegociateWindow::getEventLoop ();
//! \sreturn The RoutingEventLoop.
//! \function Stage NegociateWindow::getStage () const;
//! \sreturn The stage (NegicateWindow::Stage) into which the NegociateWindow is running.
//! \function void NegociateWindow::setGCells ( const Katabatic::GCellVector& v );
//! Sets the GCell vector from KatabaticEngine (perform a shallow copy).
//! \function void NegociateWindow::setInterrupt ( bool state );
//! Sets or unset the interruption flag.
//! \function void NegociateWindow::setStage ( Stage stage );
//! Set the stage (NegociateWindow::Stage) under which we are running.
//! \function double NegociateWindow::computeWirelength ();
//! Compute the total wirelength of the circuit. It is not completly
//! accurate because overlaps are not took into accounts.
//! \function TrackElement* NegociateWindow::createTrackSegment ( AutoSegment*, unsigned int flags );
//! Build a TrackSegment from the Katabatic::AutoSegment. If \c flags contains
//! Kite::KtLoadingStage then assume that we are in the initial loading stage
//! (constructor).
//! \function void NegociateWindow::addRoutingEvent ( TrackElement*, unsigned int level );
//! Create a new RoutingEvent from TrackElement (if it doesn't already exists)
//! and insert it into the queue with priority \c level.
//! \function void NegociateWindow::rescheduleEvent ( RoutingEvent*, unsigned int level );
//! Reschedule an event into the queue, with priority \c level.
//! \function void NegociateWindow::run ( int slowMotion=0 );
//! Perform the routing.
//!
//! \red{\c slowMotion is not implemented yet.}
//! \function void NegociateWindow::printStatistics () const
//! Display some statistics about the routing, compute the internal
//! complete statistics.
}

View File

@ -0,0 +1,597 @@
// -*- 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.

View File

@ -0,0 +1,51 @@
// -*- C++ -*-
namespace Kite {
/*! \class RoutingEventHistory
* \brief History of RoutingEvent.
*
* An history of all the routing events. We can afford to keep an
* history because while one event is a relatively big object, there
* is not that much of them (their number is roughly proportional
* to the number of TrackSegments).
*
* One event is likely to appear more than one time in the history,
* in fact it will apprears each time it is ripped up.
*
* Lastly, it is a way to keep track of all the allocated RoutingEvents.
* When history is deleted it will deleted all the events that it
* knows of.
*/
//! \function RoutingEventHistory::RoutingEventHistory ();
//! Construct an empty RoutingEventHistory.
//! \function RoutingEventHistory::~RoutingEventHistory ();
//! Delete a RoutingEventHistory.
//!
//! \remark The deletion of this object triggers the deletion of
//! all the RoutingEvent that are referenced in it.
//! \function bool RoutingEventHistory::empty () const;
//! \sreturn \true if the history is empty.
//! \function size_t RoutingEventHistory::size () const;
//! \sreturn the number of events in the history.
//! \function RoutingEvent* RoutingEventHistory::getNth ( size_t pos ) const;
//! \sreturn The event at index \c pos from the beginning of the history
//! (\c NULL if \c pos exeed the size).
//! \function RoutingEvent* RoutingEventHistory::getRNth ( size_t pos ) const;
//! \sreturn The event at index \c pos from the end of the history
//! (\c NULL if \c pos exeed the size).
//! \function void RoutingEventHistory::push ( RoutingEvent* event );
//! Push a new RoutingEvent in the history.
//! \function void RoutingEventHistory::clear ();
//! Clear the history, also remove the RoutingEvent that are pointed to.
}

View File

@ -0,0 +1,60 @@
// -*- C++ -*-
namespace Kite {
/*! \class RoutingEventLoop
* \brief Simple loop dectector for RoutingEvent.
*
* The RoutingEventLoop can be roughly understood as a truncated histogram
* of the \c depth last (in the time meaning) greatest riped up elements.
*
* The loop detector keep track of the \c depth TrackElement with the
* greatest processing count. TrackElement are just identified through
* the \c id of their associated AutoSegment. Each entry in the loop
* table contains:
* - The \c id of the associated TrackSegment (Katabatic::AutoSegment).
* - The \c count of times it has been processed
* - The \c timestamp of the latest time it has been updated.
*
* The table (implemented as \c vector<>) it kept sorted on the timestamp
* (decreasing). Whenever there is more than \c depth elements in the
* table, the oldest one are discarted (regardless of their count).
* Obviously, there are pathological cases into which a loop cannot
* be detected, but so far it has not happened so a more robust
* approach seems not necessary at this time.
*
* Whenever the count of an element reaches \c countLimit, the looping
* flag is set. It will remains set unless the faulty element is
* manually removed.
*/
//! \function RoutingEventLoop::RoutingEventLoop ( size_t depth, int countLimit );
//! Construct a loop detector that handle \c depth differents segments
//! and has a looping threshold of \c countLimit.
//! \function bool RoutingEventLoop::isLooping () const;
//! \sreturn \true if the loop threshold has been reached for at least one
//! element.
//! \function int RoutingEventLoop::getMaxCount () const;
//! The maximal count an element as reached so far.
//! \function const std::vector<Element>& RoutingEventLoop::getElements () const;
//! The complete table elements.
//! \function void RoutingEventLoop::update ( size_t id ) ;
//! Update the loop, telling that element \c id has appreared one more
//! time.
//! \function void RoutingEventLoop::erase ( size_t id ) ;
//! Remove the entry related to element \c id in the table. The state of
//! the table is fully recomputed after the removal (looping flag &
//! maximum count).
//!
//! This method is used when a loop has been encountered, presumably on
//! element \c id, and we want to continue. To avoid the loop detector
//! yelling at each check, the associated TrackElement should be invalidated
//! and it's reference removed from the table.
}

View File

@ -0,0 +1,106 @@
// -*- C++ -*-
namespace Kite {
/*! \class RoutingEventQueue
* \brief The priority Queue of RoutingEvent.
*
* \section secImplRoutingEventQueue Implementation Details
*
* The RoutingEventQueue is build upon a STL multiset<> and is sorted
* according to the RoutingEvent::Key attribute of the event. The key
* attribute has been designed specifically to be used with this queue.
* It provides the features:
* - Sort the RoutingEvent according to their priority. Higher priority
* mainly means more constrained segment, which must be routed first.
* - The attributes of RoutingEvent may change while inserted in the
* queue. The key provide a cached value of those attributes ensuring
* a stable sorting order.
*
* For more details about the sorting order, refer to RoutingEvent::Key.
*
* <b>Insertion, Reinsertion & Commit</b>
*
* When pushing a new event into the queue, the actual insertion into the
* multimap is delayed until the next call to \c RoutingEvent::commit().
* The to be inserted events are stored into a request set which is
* processed when commit is called. At commit time, the RoutingEvent::Key
* cache is updated just before inserting the element.
*
* When repushing an event, the event is immediatly withdrawn from the
* queue and put into the request set.
*
* <b>Mutiple Event for one Segment</b>
*
* As RoutingEvent can be cloned, there may be more than one event pointing
* to a segment. But there must be <em>only one active event</em>, the one
* which is pointed to by the segment. As a result, there maybe multiple
* events for an unique segment in the queue, but <em>only one active event</em>,
* the one that will be processed.
*/
//! \function RoutingEventQueue::RoutingEventQueue ();
//! Contructor, create an empty queue.
//! \function RoutingEventQueue::~RoutingEventQueue ();
//! Destructor.
//!
//! \remark The destruction of the queue do not delete the
//! RoutingEvent that may still be in it (they shouldn't an
//! a warning is issued).
//! \function bool RoutingEventQueue::empty () const;
//! \sreturn \true if there is the queue is empty.
//! \function size_t RoutingEventQueue::size () const;
//! \sreturn The number of events in the queue.
//! \function unsigned int RoutingEventQueue::getTopEventLevel () const;
//! \sreturn The greatest event level the queue has ever reached (always increasing,
//! starting from zero).
//! \function void RoutingEventQueue::load ( const vector<TrackElement*>& );
//! Load a whole vector of TrackElement into the queue, for each
//! element:
//! - Create a RoutingEvent linked to the element.
//! \red{To be reviewed: replace any previous event.}
//! - Insert the new RoutingEvent into the queue.
//!
//! <em>No commit is needed after this operation.</em>
//! \function void RoutingEventQueue::add ( TrackElement* element, unsigned int level );
//! Create a new RoutingEvent in the queue with \c level, associated to \c element.
//! A commit is needed afterwards.
//!
//! \red{To be reviewed: replace any previous event on element.}
//! \function void RoutingEventQueue::push ( RoutingEvent* event );
//! Push a RoutingEvent in the queue. Effective only after the next commit.
//! \function RoutingEvent* RoutingEventQueue::pop ();
//! Remove the top element of the queue (i.e. the one with the highest
//! priority) and return it. If the queue is empty, \c NULL is returned.
//! \function void RoutingEventQueue::repush ( RoutingEvent* event );
//! Force a complete queue re-insertion for \c event. The event is immediatly
//! withdrawn from the queue and put into the insertion request set.
//!
//! If the \c event is not already in the queue, works like
//! RoutingEventQueue::push().
//! \function void RoutingEventQueue::repushInvalidateds ();
//! Using the list of invalidated segments from the Session, repush
//! them if:
//! - They have an associated event.
//! - The event is not \e unimplemented, \e disabled or \e processed.
//! \function void RoutingEventQueue::commit ();
//! Process the insertion request set and actually insert it's elements
//! into the queue. Perform a RoutingEvent::key update prior to insertion.
//! \function void RoutingEventQueue::clear ();
//! Empty the queue. Issue a warning if the queue is not empty (i.e. some
//! events remains to be processeds).
}

95
kite/doc/RoutingPlane.dox Normal file
View File

@ -0,0 +1,95 @@
// -*- C++ -*-
namespace Kite {
/*! \class RoutingPlane
* \brief Array of Tracks in one Layer
*
* A RoutingPlane is an array of Track covering a rectangular area.
* For now the area is the abutment box of the to be routed Cell.
* Tracks are spaced evenly and according to the configuration
* of the relevant RoutingLayerGauge.
*
* \image html RoutingPlane-1.png "Fig 1: Horizontal RoutingPlane"
*/
//! \function RoutingPlane* RoutingPlane::create ( KiteEngine* engine, size_t depth );
//! \param engine The associated engine.
//! \param depth The Layer depth of the plane.
//! \return The newly created RoutingPlane.
//!
//! The RoutingPlane public constructor. The \c depth is in the sense of
//! the RoutingGauge.
//! \function bool RoutingPlane::isHorizontal () const;
//! \sreturn \true if the preferred routing direction is horizontal (the actual
//! direction of the tracks).
//! \function bool RoutingPlane::isVertical () const;
//! \sreturn \true if the preferred routing direction is vertical (the actual
//! direction of the tracks).
//! \function KiteEngine* RoutingPlane::getKiteEngine () const;
//! \sreturn The associated KiteEngine.
//! \function RoutingLayerGauge* RoutingPlane::getLayerGauge () const;
//! \sreturn The RoutingLayerGauge of the plane.
//! \function unsigned int RoutingPlane::getDirection () const;
//! \sreturn The preferred routing direction (Katabatic::KbHorizontal or Katabatic::KbVertical).
//! \function size_t RoutingPlane::getDepth () const;
//! \sreturn The depth of the associated layer (as defined by the RoutingLayerGauge).
//! \function size_t RoutingPlane::getAxisMin () const;
//! \sreturn The axis coordinate of the first/lowest track.
//! \function size_t RoutingPlane::getAxisMax () const;
//! \sreturn The axis coordinate of the last/highest track.
//! \function size_t RoutingPlane::getTrackMin () const;
//! \sreturn The minimum bound of all track.
//! \function size_t RoutingPlane::getTrackMax () const;
//! \sreturn The maximum bound of all track.
//! \function RoutingPlane* RoutingPlane::getTop () const;
//! \sreturn The RoutingPlane immediatly above this one.
//! \function RoutingPlane* RoutingPlane::getBottom () const;
//! \sreturn The RoutingPlane immediatly below this one.
//! \function const Layer* RoutingPlane::getLayer () const;
//! \sreturn The associated routing layer.
//! \function const Layer* RoutingPlane::getBlockageLayer () const;
//! \sreturn The blockage layer associated to the routing layer.
//! \function size_t RoutingPlane::getTracksSize () const;
//! \sreturn The number of tracks in the array.
//! \function size_t RoutingPlane::computeTracksSize () const;
//! \sreturn The number of tracks <em>to create</em> in the array.
//!
//! Helper method that compute the number of tracks in the array
//! from the area of the Cell to be routed and the RoutingLayerGauge
//! characteristics (the Cell is accessible through the KiteEngine).
//! \function DbU::Unit RoutingPlane::getTrackPosition ( size_t index ) const;
//! \sreturn The axis of the track at \c index in the array.
//! \function Track* RoutingPlane::getTrackByIndex ( size_t index ) const;
//! \sreturn The track at \c index in the array.
//! \function Track* RoutingPlane::getTrackByPosition ( DbU::Unit axis, unsigned int mode=KtNearest ) const;
//! \sreturn The track which position is nearest from \c axis. The meaning of
//! \e nearest is defined by \c mode (classic rouding options).
//! \function bool RoutingPlane::_check ( unsigned int& overlaps ) const;
//! \sreturn \true if no errors have been found (i.e. the database is coherent).
//!
//! Perform a coherency check on all tracks part of the array.
}

474
kite/doc/SegmentFsm.dox Normal file
View File

@ -0,0 +1,474 @@
// -*- C++ -*-
namespace Kite {
// -------------------------------------------------------------------
// Class : "SegmentAction".
/*! \class SegmentAction
* \brief Store request for an event to be generated on a TrackElement
*
* When an event on a Kite::TrackElement is being processed (with the
* SegmentFsm helper), it may generate events on TrackElement already
* placed and belonging either to the same net or other ones.
* Those events are not generated and queued immediatly but
* instead SegmentAction, requesting the event generation are created
* and stored into a simple vector in SegmentFsm. The last operation of
* the SegmentFsm object is to call the SegmentAction::doAction() method
* on all the action to actually generate and queue the events.
*/
//! \enum SegmentAction::Type
//! Indicates the kind of action to be performed on the segment. In the following
//! \b flags and \b masks descriptions, we uses the term <em>reference segment</em>
//! for the TrackElement which is associated with the currently processed RoutingEvent
//! (also referenced in SegmentFsm).
//!
//! Here is the list of the availables actions that can be performed when (re)scheduling
//! a RoutingEvent. It is here that we uses the RoutingEvent level feature to perform
//! a local reordering of the top of the queue. Reordering is used to allows
//! perpandiculars to be routed \e before the reference segment (instead of after)
//! or \e other segments in conflict.
//!
//! - SegmentAction::SelfInsert<br>
//! <b>Action:</b> The reference segment is to be inserted in a Track (placed).<br>
//! <b>Event Level:</b> Unchanged.
//!
//! - SegmentAction::SelfRipup<br>
//! <b>Action:</b> The reference segment is to be ripped up.<br>
//! <b>Event Level:</b> Unchanged.
//!
//! - SegmentAction::SelfRipupPerpand<br>
//! <b>Action:</b> Ripup a segment which is a perpandicular to the reference
//! segment. Ordering considerations: this perpandicular will be put back into
//! the RoutingEvent queue with a lower level (priority) than the reference
//! segment, so it will be processed again \e after the reference segment.<br>
//! <b>Event Level:</b> Unchanged.
//!
//! - SegmentAction::SelfRipupPerpandWithAxisHint<br>
//! <b>Action:</b> Ripup a segment which is a perpandicular to the reference
//! segment, supplies an axis hint and put it back into the RoutingEvent queue so
//! that it will be processed \e before the reference segment.<br>
//! <b>Event Level:</b> Increased to SegmentAction::EventLevel4.
//!
//! - SegmentAction::OtherRipup<br>
//! <b>Action:</b> Ripping up a segment from another net and in the same direction
//! as the reference segment.<br>
//! <b>Event Level:</b> Unchanged.
//!
//! - SegmentAction::OtherRipupPerpandAndPushAside<br>
//! <b>Action:</b> Ripping up a segment from another net and in perpandicular
//! direction. The level is elevated so it's priority is greater than the
//! reference segment this it will be reprocessed first. An axis hint is also
//! supplied in order to make room for the reference segment.<br>
//! <b>Event Level:</b> Increased to SegmentAction::EventLevel3.
//!
//! - SegmentAction::OtherRipupPerpandAndPacking<br>
//! <b>Action:</b> Ripping up a segment from another net and in perpandicular
//! direction. The level is elevated so it's priority is greater than the
//! reference segment this it will be reprocessed first. The generated event
//! is in packing mode only.<br>
//! <b>Event Level:</b> Increased to SegmentAction::EventLevel4.
//! \var SegmentAction::Self
//! <b>[Flag]</b> The segment associated to the action is the reference segment
//! <em>or segments from the same net</em>.
//! \var SegmentAction::Other
//! <b>[Flag]</b> The segment associated to the action is \b not from the same
//! net as the reference segment.
//! \var SegmentAction::Perpandicular
//! <b>[Flag]</b> The action concern a perpandicular to the reference segment.
//! \var SegmentAction::Ripup
//! <b>[Flag]</b> Request that the segment is to be ripped up.
//! \var SegmentAction::RipedByLocal
//! <b>[Flag]</b> Indicate that the segment has been ripped up by a local one.
//! \var SegmentAction::ResetRipup
//! <b>[Flag]</b> The ripup count is to be reset.
//! \var SegmentAction::ToRipupLimit
//! <b>[Flag]</b> The ripup count is directly increased to the ripup limit,
//! triggering a state change the next time the segment will be processed.
//! \var SegmentAction::Insert
//! <b>[Flag]</b> Request that the segment is to be inserted in the given track.
//! It is the task of SegmentFsm to determine that there is sufficent space to do so.
//! \var SegmentAction::AxisHint
//! <b>[Flag]</b> An axis hint has been supplied, and is to be passed to
//! the generated RoutingEvent.
//! \var SegmentAction::PackingMode
//! <b>[Flag]</b> Whether the RoutingEvent should be processed in \e packing
//! mode or \e negociated mode (transmitted to the RoutingEvent).
//! \var SegmentAction::ToState
//! <b>[Flag]</b> Force the change of state of the RoutingEvent
//! (i.e. DataNegociate). Normally the state change is done through the
//! increase of the ripup count in DataNegociate.
//! \var SegmentAction::EventLevel1
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 1.
//! \var SegmentAction::EventLevel2
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 2.
//! \var SegmentAction::EventLevel3
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 3.
//! \var SegmentAction::EventLevel4
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 4.
//! \var SegmentAction::EventLevel5
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 5.
//! \var SegmentAction::SelfInsert
//! <b>[Mask]</b>, see SegmentAction::Type.
//! \var SegmentAction::SelfRipup
//! <b>[Mask]</b>, see SegmentAction::Type.
//! \var SegmentAction::SelfRipupPerpand
//! <b>[Mask]</b>, see SegmentAction::Type.
//! \var SegmentAction::SelfRipupPerpandWithAxisHint
//! <b>[Mask]</b>, see SegmentAction::Type.
//! \var SegmentAction::OtherRipup
//! <b>[Mask]</b>, see SegmentAction::Type.
//! \var SegmentAction::OtherRipupPerpandAndPushAside
//! <b>[Mask]</b>, see SegmentAction::Type.
//! \var SegmentAction::OtherRipupPerpandAndPacking
//! <b>[Mask]</b>, see SegmentAction::Type.
//! \function SegmentAction::SegmentAction ( TrackElement* segment, unsigned int type, DbU::Unit axisHint=0, unsigned int toState =0 );
//! \param segment On what the action is to be performed.
//! \param type Defines the type of action, see SegmentAction::Type.
//! \param axisHint Specifies a preferred axis.
//! \param toState The DataNegociate::SlackState into which the segment is to be set.
//!
//! Create segment action.
//! \function TrackElement* SegmentAction::getSegment () const;
//! \sreturn The associated \c segment.
//! \function SegmentAction::Type SegmentAction::getType () const;
//! \sreturn The action to be performed.
//! \function void SegmentAction::setAxisHint ( DbU::Unit axis );
//! The axis preferred position to be transmitted to the generated event.
//! The transmition will be effective \e only if the SegmentAction::Type::AxisHint
//! flag is set.
//! \function unsigned int SegmentAction::setFlag ( unsigned int flags );
//! Allow to change the action type by indivually setting up the flags.
//! \function void SegmentAction::doAction ( RoutingEventQueue& queue );
//! Actually perform the action. That is, build and queue the appropriate
//! event for the segment.
// -------------------------------------------------------------------
// Class : "SegmentFsm".
/*! \class SegmentFsm
* \brief Pseudo-decorator to process a RoutingEvent
*
* The SegmentFsm class actually perform the placement of the Kite::TrackElement
* of the Kite::RoutingEvent. It structured around three goals:
* - Implement the finite state machine for the Kite::DataNegociate state.
* - Provide a kind of decoration on the RoutingEvent/TrackElement
* (it do not abide by the definition from Design Patterns).
* - Cache a lot of on-the-fly computed datas needed during the
* SegmentFsm lifetime and the Manipulator(s) it may uses.
*
*
* \section secUpdate Update Mechanism
*
* The constructor of SegmentFsm triggers the update of the RoutingEvent
* and through it DataNegociate.
*
*
* \section secSlackening Slackening / FSM Transitions
*
* A transition occurs in the FSM whenener all the availables ripup methods
* for a segment have failed. Failure means that the topology of the net
* itself must be altered to allow a greater level of flexibility.
* Modifying the net topology means to give the current segment some
* more slack.
*
* Availables slackening operations:
* -# DataNegociate::RipupPerpandiculars (Manipulator) place the segments before any of
* it's perpandiculars are placed to allow a maximum track choice.
* -# DataNegociate::Minimize (Manipulator) try to fit the segment in a hole in a track,
* perform a hole detection.
* -# DataNegociate::Dogleg (Manipulator) create a dogleg matching <em>the first track
* candidate</em> with a non-nul overlap.
* -# DataNegociate::Slacken (Manipulator) \red{to be reviewed.}
* -# DataNegociate::ConflictSolveByHistory (SegmentFsm) try to find a break point on
* the segment, based on the ripup history.
* -# DataNegociate::ConflictSolveByPlaceds (SegmentFsm) try to find a break point on
* the segment, based on the current position of segments on the
* candidate tracks.
* -# DataNegociate::MoveUp (Manipulator) try to move up the segment.
*
* Simple slackening operations are defined in Manipulator and complex ones
* directly in SegmentFsm.
*
*
* \section secNonSlackening Non-Slackening Operations
*
* In addition, some operation that do not modifies the topology are
* availables:
* -# Manipulator::forceOverLocals() mostly for global segments to ripup
* a track from all it's locals.
* -# SegmentFsm::insertInTrack() automates the three subsequent ripup
* trials.
*/
//! \enum SegmentFsm::State
//! Indicates what the SegmentFsm has done the processed TrackElement,
//! possible values are:
//! - SegmentFsm::MissingData, this is an error condition, the TrackElement
//! do not have associated DataNegociate structure. Nothing is done.
//!
//! - SegmentFsm::EmptyTrackList, no Track is available for placement
//! (free or used).
//!
//! - SegmentFsm::SelfInserted, the TrackElement can be successfully
//! inserted in a Track (i.e. without overlap).
//!
//! - SegmentFsm::SelfMaximumSlack, nothing can be done to further slacken
//! the TrackElement, it is at maximum ripup of the last possible state
//! (no more topological modifications are possibles).
//!
//! - SegmentFsm::OtherRipup, the TrackElement can be inserted but it
//! needs the ripup of some others.
//! \var SegmentFsm::MissingData
//! <b>[Flag]</b>, see SegmentFsm::SegmentFsmValue.
//! \var SegmentFsm::EmptyTrackList
//! <b>[Flag]</b>, see SegmentFsm::SegmentFsmValue.
//! \var SegmentFsm::Inserted
//! <b>[Flag]</b>, the TrackElement can be inserted in a Track.
//! \var SegmentFsm::Self
//! <b>[Flag]</b>, the action is related to the processed TrackSegment.
//! \var SegmentFsm::Other
//! <b>[Flag]</b>, the action is \b not related to the processed TrackSegment,
//! that is, others are being topologically modificated or riped up.
//! \var SegmentFsm::Ripup
//! <b>[Flag]</b>, segement, that are not the processed one are being ripped up.
//! \var SegmentFsm::MaximumSlack
//! <b>[Flag]</b>, the processed segment as reached it's maximum ripup count on
//! the last possible slackening state.
//! \var SegmentFsm::SelfInserted
//! <b>[Mask]</b>, see SegmentFsm::SegmentFsmValue.
//! \var SegmentFsm::OtherRipup
//! <b>[Mask]</b>, see SegmentFsm::SegmentFsmValue.
//! \var SegmentFsm::SelfMaximumSlack
//! <b>[Mask]</b>, see SegmentFsm::SegmentFsmValue.
//! \function SegmentFsm::SegmentFsm ( RoutingEvent* event, RoutingEventQueue& queue, RoutingEventHistory& history );
//! \param event The RoutingEvent to be processed.
//! \param queue The RoutingEvent queue.
//! \param history The complete history of RoutingEvent.
//!
//! Construct a SegmentFsm from a RoutingEvent. The constructor is in charge of
//! computing all the cached values.
//! \function bool SegmentFsm::isFullBlocked () const;
//! \sreturn \true if there are Tracks avalaibles but the constraints are such that none
//! is actually usable.
//! \function RoutingEvent* SegmentFsm::getEvent () const;
//! \sreturn The currently processed RoutingEvent (\e cached).
//! \function RoutingEventQueue& SegmentFsm::getQueue () const;
//! \sreturn The RoutingEvent queue (\e cached).
//! \function RoutingEventHistory& SegmentFsm::getHistory () const;
//! \sreturn The RoutingEvent history (\e cached).
//! \function DataNegociate* SegmentFsm::getData ();
//! \sreturn The DataNegociate of the TrackElement (\e cached).
//! \function unsigned int SegmentFsm::getState () const;
//! \sreturn The state (SegmentFsm::SegmentFsmValues) which the SegmentFsm has computed for the
//! RoutingEvent. This is \b not the state of the DataNegociate
//! \function Interval& SegmentFsm::getConstraint ();
//! \sreturn The interval into which the segment axis can be set (computed from
//! the topological constraints and the placement constraints on the
//! already placed perpandiculars).
//! \function Interval& SegmentFsm::getOptimal ();
//! \sreturn The interval for an optimal placement of the segment axis.
//! \function vector<TrackCost>& SegmentFsm::getCosts ();
//! \sreturn The table of cost for all the candidates Tracks of the segment.
//! The table is sorted in increasing cost order (see TrackCost).
//! \function TrackCost& SegmentFsm::getCost ( size_t i );
//! \sreturn The cost at index \c i in the table.
//! \function Track* SegmentFsm::getTrack ( size_t i );
//! \sreturn The Track for cost at index \c i in the table.
//! \function size_t SegmentFsm::getBegin ( size_t i );
//! \sreturn The overlapping \e begin index in Track for cost at index \c i in the table.
//! \function size_t SegmentFsm::getEnd ( size_t i );
//! \sreturn The overlapping \e end index in Track for cost at index \c i in the table.
//! \function vector<SegmentAction*>& SegmentFsm::getActions ();
//! \sreturn The table of SegmentAction, that is the delayed requests for RoutingEvent
//! creation.
//! \function unsigned int SegmentFsm::setState ( unsigned int state );
//! \sreturn Sets the state of the state...
//! \function void SegmentFsm::addAction ( TrackElement* segment, unsigned int type, DbU::Unit axisHint=0, unsigned int toState=0 );
//! Request the creation of a new delayed RoutingEvent, for the meaning of
//! the parameters, see SegmentAction::SegmentAction.
//! \function bool SegmentFsm::doActions ();
//! Actually generate RoutingEvent(s) from the SegmentAction(s).
//! \function void SegmentFsm::clearActions ();
//! Clear the the table of requested actions, whithout generating them.
//! \function void SegmentFsm::clearActions ();
//! Clear the the table of requested actions, whithout generating them.
//! \function bool SegmentFsm::insertInTrack ( size_t i );
//! Try to insert the TrackElement in the Track at index \c i (in the
//! cost table). Return \true if the insertion is possible.
//!
//! The insertion is not done at this stage, but a set of ripup actions is
//! emitted to allow insertion the next time the segment will be processed.
//!
//! Three subsequent trials are done before giving up on inserting
//! the segment:
//! -# Manipulator::insertInTrack(), try to push asides the neighbors.
//! -# Manipulator::shrinkToTrack(), try squeeze the segment in an existing
//! free space.
//! -# Manipulator::forceToTrack(), perform a complete ripup of all the
//! neighbors and their perpandiculars.
//!
//! The event keeps track of the insertion attempt step (see RoutingEvent::getInsertState()).
//! \function bool SegmentFsm::conflictSolveByHistory ();
//! \sreturn \true if a suitable dogleg has been created in the segment.
//!
//! Initially, global segments may be very long, and a placement solution
//! in which each one is placed on a track of it's own may not be realisable.
//! In that case, at least one of the global segment must be broken.
//! The figure below illustrate the case: <b>(a)</b>, <b>(b)</b>, <b>(c)</b> form a
//! first cluster and <b>(d)</b>, <b>(e)</b>, <b>(f)</b> form a second one. Due to the
//! constraints of the segments the remaining free track cannot be the same
//! in both clusters. The only solution to place <b>(g)</b> is to break it into
//! two sub-globals. The whole point of the conflict solve is to correctly
//! detect the cluster and choose the breaking point.
//!
//! \image html ConflictSolve-1.png "Conflict Between Globals"
//!
//! This variant of the conflict solve method try to guess the track span
//! for which there is a conflict by looking at the event history.
//!
//! \image html ConflictSolveByHistory-1.png "Building Conflicting Intervals"
//!
//! <b>Dislodger Definition:</b>
//!
//! A segment is said to be a dislodger if it matches the two following criterions:
//! - It's span intersect the to be inserted segment span.
//! - It has been placed on a track inside the perpandicular span of the
//! to be placed segment.
//!
//! For the time beeing we limit the search to the last three dislodgers, to not
//! waste too much time looking back the event history. We merge overlapping
//! intervals into one (see the undocumented class \c UnionIntervals and
//! \c RipupHistory in \c SegmentFsm.cpp).
//!
//! \red{For the time beeing we only look on the track into which}
//! \red{the to be inserted segment wants to be placed.}
//!
//! Then we try to break the to be placed segment, first under the lower bound
//! (source) of the conflicting interval then, in case of failure under
//! the upper bound (target).
//!
//! \image html ConflictSolveByHistory-2.png "Interval Breaking"
//! \function bool SegmentFsm::conflictSolveByPlaceds ();
//! \sreturn \true if a suitable dogleg has been created in the segment \e or a
//! dislodger has been moved up.
//!
//! This methods achieve the same goal as SegmentFsm::conflictSolveByHistory()
//! but uses a different strategy.
//!
//! Instead of looking through the history to find dislodgers it analyses
//! the placed segments in all the candidates tracks for the to be placed
//! segment. Unlike it's sibling method, which creates only one dogleg, as
//! it uses the Manipulator::relax() method, it may creates up to two doglegs.
//!
//! <b>Synthetic Description</b>
//!
//! -# For each track, find the dislodgers, merge the overlaps into one
//! interval and store the length of the longuest overlap (aka conflict).
//! -# Sort the tracks according to decreasing longuest overlap/confict.
//! -# For each track in the sorted list, look for a dislodger under the middle
//! of the to be placed segment. If no dislodger is present at this place
//! go to the next track. Otherwise:
//! - <em>The dislodger is local</em>, then try to relax the to placed
//! segment around the dislodger.
//! - <em>The dislodger is global</em>, try to move it up, if it is not
//! possible, fallback to the relax approach.
//! -# Quit on the first successful move up or relax.
//! -# If there is no candidate tracks, this means the vertical constraints
//! are too tight, in that case, ripup the perpandiculars (fallback plan).
//!
//! <b>Interval Accounting</b>
//!
//! Only global conflicting segments are took into account. Local segments
//! may be took into account if they overlap global ones (all part of the
//! same net). All overlapping segments are merged into one big conflict
//! interval. The whole length of a conflict interval is took into account
//! event if it's overlap with the to be placed segment is only partial.
//!
//! <b>Track Ordering (lexicographic)</b>
//!
//! -# The longuest (in one interval) conflict length.
//! -# The longuest cumulative conflict length (all interval summed up).
//!
//! Interval accounting and Track ordering is managed through the undocumented
//! \c Cs1Candidate class implemented in \c SegmentFsm.cpp.
//!
//! \image html ConflictSolveByPlaceds-1.png "Candidates Track Ordering"
//! \function bool SegmentFsm::desaturate ();
//! Try to create a suitable empty space in a cost Track by moving up
//! TrackElement in conflict.
//! \function bool SegmentFsm::slackenTopology ( unsigned int flags=0 );
//! Modificate the topology of the TrackElement to slacken it.
//! It is the implementation of the slakening finite state machine.
//! \function bool SegmentFsm::solveFullBlockages ();
//! Try to solve a fully blocked configuration.
}

559
kite/doc/SoC.css Normal file
View File

@ -0,0 +1,559 @@
/*
* +-----------------------------------------------------------------+
* | HTML Standart Tags |
* +-----------------------------------------------------------------+
*/
html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 {
font-size: 11pt;
/* The Open Sans font family is supplied by TexLive. */
font-family: "Open Sans", Verdana, sans-serif;;
}
body {
color: black;
background: white;
background-color: white;
background-position: top left;
background-attachment: fixed;
background-repeat: no-repeat;
margin-top: 2em;
width: 550pt;
margin-right: auto;
margin-left: auto;
/*
margin-right: 12%;
margin-left: 12%;
*/
}
hr {
height: 1px;
border: 0;
color: #004400;
background-color: #004400;
}
h1, h2, h3, h4, h5, h6 {
/*font-family: "Liberation Serif", sans-serif;*/
}
h1 { text-align: center; }
h2, h3, h4, h5, h6 { text-align: left;
padding-top: 11pt;
}
h1, h2, h3 { /*font-family: "Liberation Serif", sans-serif; */
/*color: #09550B;*/
}
h1 { font-weight:normal; font-size: 170%; letter-spacing:0.2em; word-spacing:0.4em; }
h2 { font-weight:normal; font-size: 140%; letter-spacing:0.2em; word-spacing:0.4em; }
h3 { font-weight: bold; font-size: 118%; letter-spacing:0.2em; word-spacing:0.4em; }
h4 { font-weight: bold; font-size: 100%; }
h5 { font-style: italic; font-size: 100%; }
h6 { font-variant: small-caps; font-size: 100%; }
h2.classHierarchy {
/*border: 1px none #008500;*/
border: 1px none #000000;
border-top-width: 1px;
border-top-style: dotted;
padding-top: 1em;
}
.hide {
display: none;
color: white;
}
p {
margin-top: 0.6em;
margin-bottom: 0.6em;
margin-left: 0.0em;
margin-right: 0.0em;
}
address {
text-align: right;
font-weight: bold;
font-style: italic;
font-size: 80%;
}
caption { font-weight: bold }
blockquote {
margin-left: 4em;
margin-right: 4em;
margin-top: 0.8em;
margin-bottom: 0.8em;
font-style: italic;
color: #003300;
}
blockquote p {
margin-bottom: 0;
}
blockquote address {
margin: 0;
}
table {
border-collapse: collapse;
}
dt, dd { margin-top: 0; margin-bottom: 0; }
dt { font-weight: bold; }
pre, tt, code {
/*font-family: "andale mono", monospace;*/
font-size: 100%;
white-space: pre;
}
pre {
font-size: 80%;
border: dashed;
border-width: thin;
border-color: #003300;
/*
background-color: #EEEEEE;
*/
background-color: #FCFCE1;
padding: 0.5em;
margin-left: 2em;
margin-right: 2em
}
tt { color: green; }
em { font-style: italic;
font-weight: normal; }
strong { font-weight: bold; }
span.textit { font-style: italic; }
span.textbf { font-weight: bold; }
.small { font-size: 90%; }
.white { color: #FFFFFF; }
ul.toc {
list-style: disc;
list-style: none;
}
a:link img, a:visited img { border-style: none; }
a img { color: white; }
a:link, a:active, a:visited {
color: #09550B;
text-decoration: none;
}
a:hover, a:focus {
color: #FF9900;
text-decoration: underline;
}
/*
* +-----------------------------------------------------------------+
* | Doxygen Specific Classes |
* +-----------------------------------------------------------------+
*/
/* -------------------------------------------------------------------
* Header & Footer Classes (customized top page navigation bar).
*/
h1.header {
font-size: 200%;
/*font-family: times, verdana, sans-serif;*/
}
center.header {
background-color: #CCE6CA;
}
table.header {
/*width: 100%;*/
/*background-color: #EEEEEE;*/
background-color: #CCE6CA;
}
table.header td {
padding: 2px 14px;
text-align: center;
font-weight: bold;
/*font-family: verdana, sans-serif;*/
font-size: 110%;
}
table.DoxUser td, table.DoxUser th {
padding: 0px 5px;
border: 0px;
}
table.DoxUser th {
background-color: #CCE6CA;
}
table.footer1, table.footer2 { width: 100%; }
td.LFooter { text-align: left; }
td.RFooter { text-align: right; }
td.CFooter { text-align: center;}
table.footer2 td.RFooter { font-weight: bold; width: 35% }
table.footer2 td.CFooter { width: 30% }
table.footer2 td.LFooter { font-weight: bold; width: 35%; /*font-family: time;*/ }
table.classHierarchy {
border-collapse: separate;
border-spacing: 5px;
font-size: 110%;
}
table.classHierarchy tr {
border: 1px solid blue;
}
table.classHierarchy td.normal {
border: 1px solid #CCE6CA;
width: 140pt;
text-align: center;
font-weight: bold;
background-color: #CCE6CA;
}
table.classHierarchy td.virtual {
border: 1px solid black;
width: 140pt;
text-align: center;
font-weight: bold;
}
table.classHierarchy td.wnormal {
border: 1px solid #CCE6CA;
width: 240pt;
text-align: center;
font-weight: bold;
background-color: #CCE6CA;
}
table.classHierarchy td.wvirtual {
border: 1px solid black;
width: 240pt;
text-align: center;
font-weight: bold;
}
div.ah {
/*font-family: time;*/
font-size: 250%;
}
/* -------------------------------------------------------------------
* Quick Index Class (top page navigation bar).
*/
div.qindex, div.nav {
width: 100%-4px;
/*background-color: #DADAEF;*/
/*background-color: #eeeeff;*/
/*background-color: #EEEEEE;*/
background-color: #CCE6CA;
border: 0px solid #003300;
text-align: center;
margin: 0px;
padding: 2px;
line-height: 140%;
}
a.qindex, a.qindex:visited, a.qindex:hover, a.qindexHL, a.el, a.elRef {
text-decoration: none;
/*font-family: Courier;*/
font-weight: normal;
/*font-size: 110%;*/
}
a.qindex, a.qindex:visited {
color: #09550B;
}
a.qindex:hover {
background-color: #ddddff;
}
a.qindexHL, a.qindexHL:hover, a.qindexHL:visited {
background-color: #0c780c;
color: #ffffff;
border: 1px double #9295C2;
}
a.code:link, a.code:visited, a.codeRef:link, a.codeRef:visited {
text-decoration: none;
font-weight: normal;
color: #0000ff;
}
.indexkey {
background-color: #eeeeff;
border: 1px solid #b0b0b0;
padding: 2px 15px;
}
.indexkey, .indexvalue {
background-color: #eeeeff;
border: 1px solid #b0b0b0;
padding: 2px 15px;
}
.indexkey {
width: 40%;
}
.indexvalue {
width: 80%;
}
h3 a[name="index__"],
h3 a[name="index_a"],
h3 a[name="index_b"],
h3 a[name="index_c"],
h3 a[name="index_d"],
h3 a[name="index_e"],
h3 a[name="index_f"],
h3 a[name="index_g"],
h3 a[name="index_h"],
h3 a[name="index_i"],
h3 a[name="index_j"],
h3 a[name="index_k"],
h3 a[name="index_l"],
h3 a[name="index_m"],
h3 a[name="index_n"],
h3 a[name="index_o"],
h3 a[name="index_p"],
h3 a[name="index_q"],
h3 a[name="index_r"],
h3 a[name="index_s"],
h3 a[name="index_t"],
h3 a[name="index_u"],
h3 a[name="index_v"],
h3 a[name="index_w"],
h3 a[name="index_x"],
h3 a[name="index_y"],
h3 a[name="index_z"],
h3 a[name="index_0"],
h3 a[name="index_1"],
h3 a[name="index_2"],
h3 a[name="index_3"],
h3 a[name="index_4"],
h3 a[name="index_5"],
h3 a[name="index_6"],
h3 a[name="index_7"],
h3 a[name="index_8"],
h3 a[name="index_9"]
h3 a[id="index__"],
h3 a#index_a,
h3 a#index_b,
h3 a#index_c,
h3 a#index_d,
h3 a#index_e,
h3 a#index_f,
h3 a#index_g,
h3 a#index_h,
h3 a#index_i,
h3 a#index_j,
h3 a#index_k,
h3 a#index_l,
h3 a#index_m,
h3 a#index_n,
h3 a#index_o,
h3 a#index_p,
h3 a#index_q,
h3 a#index_r,
h3 a#index_s,
h3 a#index_t,
h3 a#index_u,
h3 a#index_v,
h3 a#index_w,
h3 a#index_x,
h3 a#index_y,
h3 a#index_z,
h3 a#index_0,
h3 a#index_1,
h3 a#index_2,
h3 a#index_3,
h3 a#index_4,
h3 a#index_5,
h3 a#index_6,
h3 a#index_7,
h3 a#index_8,
h3 a#index_9,
h3 a#index_0x7e
{
font-family: time;
font-size: 250%;
}
/* -------------------------------------------------------------------
* Verbatim Source Code / Examples.
*/
/* pre.fragment { background-color: #EEEEEE; } */
span.keyword { color: #008000 }
span.keywordtype { color: #604020 }
span.keywordflow { color: #e08000 }
span.comment { color: #800000 }
span.preprocessor { color: #806020 }
span.stringliteral { color: #002080 }
span.charliteral { color: #008080 }
span.red { color: red }
/* -------------------------------------------------------------------
* Attributes Listing.
*/
p.formulaDsp {
text-align: center;
}
.mdTable {
/*border: 1px solid #868686;*/
/*background-color: #DADAEF;*/
/*background-color: #F4F4FB;*/
border: 1px none #008500;
border-left-width: 1px;
border-left-style: solid;
/*background-color: #B8E6B8;*/
/*background-color: #CCE6CA;*/
margin-top: 25px;
font-size: 105%;
}
.mdRow {
padding: 5px 10px;
}
/* This Mozilla/Firefox bug has been corrected from v1.5.
* .mdname1 {
* padding: 3px 0px 0px 0px;
* }
*/
.mdescLeft, .mdescRight {
padding: 0px 8px 4px 8px;
font-size: 11px;
font-style: italic;
/*background-color: #FAFAFA;*/
border-top: 1px none #E0E0E0;
border-right: 1px none #E0E0E0;
border-bottom: 1px none #E0E0E0;
border-left: 1px none #E0E0E0;
margin: 0px;
}
.memitem {
margin-bottom: 30px;
border: 1px none #008500;
}
.memproto {
background-color: #CCE6CA;
border-left-width: 4px;
border-left-style: solid;
border-color: #008500;
}
.memname {
white-space: nowrap;
padding-left: 5px;
font-size: 105%;
}
table.memname * {
font-family: "Monospace";
}
.memdoc{
padding-left: 5px;
/*margin-top: -8px;*/
border-left-width: 1px;
border-left-style: solid;
border-color: #008500;
}
div.contents * table tr {
padding: 3px 3px 3px 8px;
}
.memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight {
/*padding: 1px 0px 0px 8px;*/
padding: 3px 3px 3px 8px;
margin: 4px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
/*
border-top-color: #0c0c0c;
border-right-color: #0c0c0c;
border-bottom-color: #0c0c0c;
border-left-color: #0c0c0c;
*/
border-top-style: none;
border-right-style: none;
border-bottom-style: dotted;
border-left-style: none;
/*background-color: #DADAEF;*/
/*background-color: #eeeeff;*/
/*background-color: #EEEEEE;*/
/*background-color: #CCE6CA;*/
font-family: "Monospace";
}
.memTemplItemLeft, .memTemplItemRight {
border-bottom-width: 2px;
border-bottom-style: solid;
font-weight: bold;
}
.memItemLeft { font-size: 11px; width: 35%; }
.memItemRight { font-size: 12px; }
.memTemplItemLeft { font-size: 11px; }
.memTemplItemRight { font-size: 12px; }
.memTemplParams {
color: #FFFFFF;
background-color: #000000;
font-size: 11px;
font-weight: bold;
}
.groupText, .groupHeader {
color: #09550B;
font-size: 130%;
font-weight: bold;
margin-top: 15px;
}
.groupHeader {
margin-bottom: -30pt;
}

308
kite/doc/TrackElement.dox Normal file
View File

@ -0,0 +1,308 @@
// -*- C++ -*-
namespace Kite {
//! \typedef SegmentOverlapCostCB
//! Prototype of overlap cost callback functions.
//!
//! \sa TrackSegment::setOverlapCostCB(), TrackSegment::getOverlapCost().
/*! \class TrackElement
*
* \brief Abstract Class for all Elements inserted inside a Track.
*
*
* \section secTrackElementAbstract TrackElement Abstract
*
* The TrackElement class is abstract and is used as base class for
* any element that can be inserted in a Track. It represent the
* footprint of that element inside the Track (an interval).
* Additionnaly it keep a pointer to the Track and it's index inside
* it (Track is implemented with a \c vector<>).
*
* To avoid some explicit dynamic cast later, it provides a default
* implementation for almost all the methods that will be present
* in all the derived classes. All default methods return \c false,
* \c NULL or \c 0 (\e zero) or whatever is appropriated to tell
* it is not meaningful.
*
* <b>Design Note</b>
*
* TrackElement has been designed to serve as a base class for TrackSegment
* and TrackMarker. But, in the end, those two classes have been put in
* separated vectors inside the Track, thus rendering this design choice
* less pertinent. We keep it for now because we may introduce other
* object than TrackSegment inside a Track. If the need do not arise,
* we may merge back TrackElement and TrackSegment.
*/
//! \function bool TrackElement::isFixed() const;
//! \sa Katabatic::AutoSegment::isFixed().
//! \function bool TrackElement::isHorizontal() const;
//! \sa Katabatic::AutoSegment::isHorizontal().
//! \function bool TrackElement::isVertical() const;
//! \sa Katabatic::AutoSegment::isVertical().
//! \function bool TrackElement::isLocal() const;
//! \sa Katabatic::isLocal().
//! \function bool TrackElement::isGlobal() const;
//! \sa Katabatic::AutoSegment::isGlobal().
//! \function bool TrackElement::isBipoint() const;
//! \sa Katabatic::AutoSegment::isBipoint().
//! \function bool TrackElement::isTerminal() const;
//! \sa Katabatic::AutoSegment::isTerminal().
//! \function bool TrackElement::isStrap() const;
//! \sa Katabatic::AutoSegment::isStrap().
//! \function bool TrackElement::isSlackened() const;
//! \sa Katabatic::AutoSegment::isSlackened().
//! \function bool TrackElement::isDogleg() const;
//! \sa Katabatic::isDogleg().
//! \function bool TrackElement::isInvalidated() const;
//! \sreturn \true if the segment is invalidated (may be different from
//! the supporting AutoSegment status).
//! \function bool TrackElement::isCreated() const;
//! \sa Katabatic::AutoSegment::isCreated().
//! \function bool TrackElement::isBlockage() const;
//! \true if the element is a blockage (obstacle).
//! \function bool TrackElement::isLocked() const;
//! \true if the element is part of a net, but must not be
//! moved by the router, whatever the reason.
//! \function bool TrackElement::isRouted() const;
//! \true if the router has placed it.
//! \function bool TrackElement::hasSourceDogleg() const;
//! \red{This method purpose has not been reviewed yet}.
//! \function bool TrackElement::hasTargetDogleg() const;
//! \red{This method purpose has not been reviewed yet}.
//! \function bool TrackElement::canRipple() const;
//! \red{This method purpose has not been reviewed yet}.
//! \function bool TrackElement::canDogleg();
//! \sa AutoSegment::canDogleg(). At Kite level, this variant of the method
//! will apply only on local segments and the segment must not already have
//! a source or target dogleg.
//! \function bool TrackElement::canDogleg( Interval );
//! \sa AutoSegment::canDogleg(). At Kite level, this variant of the method
//! will apply only on local segments and the segment must not already have
//! a source or target dogleg.
//! \function bool TrackElement::canDogleg( Katabatic::GCell* doglegGCell, unsigned int flags );
//! \sa AutoSegment::canDogleg(). At kite level, this variant of the method
//! is mainly targeted to global segment. For local segment it behave like
//! TrackElement::canDogleg(Interval). For global segment, make the break in
//! the requested GCell \c doglegGCell. If it's in the first or last GCell
//! and there is already a dogleg, allow to reuse it if \c flags contains
//! Kite::KtAllowDoglegReuse.
//! \function unsigned long TrackElement::getId() const;
//! \return The \c Id of the supporting AutoSegment, if there is any.
//! \e Zero otherwise.
//! \function unsigned int TrackElement::getDirection() const;
//! \return The direction of the supporting element (should match the
//! preferred direction of the Track).
//! \function Net* TrackElement::getNet() const;
//! \sreturn The Net associated to the element (may be \c NULL).
//! \function const Layer* TrackElement::getLayer() const;
//! \sreturn The Layer of the element (should match the one of the Track).
//! \function Track* TrackElement::getTrack() const;
//! \sreturn The Track into which the element is inserted (may be \c NULL).
//! \function size_t TrackElement::getIndex() const;
//! \sreturn The index of the element inside the Track's vector.
//!
//! \remark If the element is not inserted in a Track, it is set to
//! Track::npos, and obviously must not be used.
//! \function unsigned long TrackElement::getFreedomDegree() const;
//! \sreturn The degree of freedom of the element. It is used as a priority value
//! when sorting TrackElement (in RoutingEvent).
//! \function float TrackElement::getMaxUnderDensity ( unsigned int flags=0 ) const;
//! \sreturn The maximum density of all the GCells under this element.
//! \function Box TrackElement::getBoundingBox() const;
//! \sreturn The box that this element uses in the Track.
//! \function TrackElement* TrackElement::getPrevious() const;
//! \sreturn The previous TrackElement, on the same track and of a \e different net.
//! \sa Track::getPrevious().
//! \function TrackElement* TrackElement::getNext() const;
//! \sreturn The next TrackElement, on the same track and of a \e different net.
//! \sa Track::getNext().
//! \function DbU::Unit TrackElement::getAxis() const;
//! \sreturn The axis position of the element (must be the same as the Track).
//! \function DbU::Unit TrackElement::getSourceU() const;
//! \sreturn The minimun of the interval used by the element (cached in an
//! attribute).
//! \function DbU::Unit TrackElement::getTargetU() const;
//! \sreturn The maximum of the interval used by the element (cached in an
//! attribute).
//! \function DbU::Unit TrackElement::getLength() const;
//! \sreturn The length of the interval used by the element.
//! \function Interval TrackElement::getCanonicalInterval() const;
//! \sreturn The interval span used by the element inside the Track.
//! \function Interval TrackElement::getFreeInterval() const;
//! \sreturn The greatest free interval enclosing this element.
//! \function Interval TrackElement::getSourceConstraints() const;
//! \sa Katabatic::AutoSegment::getSourceConstraints().
//! \function Interval TrackElement::getTargetConstraints() const;
//! \sa Katabatic::AutoSegment::getTargetConstraints().
//! \function DataNegociate* TrackElement::getDataNegociate ( unsigned int flags=KtDataSelf ) const;
//! \sreturn The additional data-structure supplied by the routing algorithm.
//! \function TrackElement* TrackElement::getCanonical ( Interval& i );
//! \red{Inner working still unclear to myself.}
//! \function size_t TrackElement::getGCells ( Katabatic::GCellVector& gcells ) const;
//! \sreturn The table of Katabatic::GCell underneath the element whole span.
//! \function unsigned int TrackElement::getDoglegLevel() const;
//! \sreturn The deepness of the dogleg.
//! \function TrackElement* TrackElement::getParent() const;
//! \sreturn The TrackElement from which the dogleg has been created, if any.
//! \function TrackElement* TrackElement::getSourceDogleg ();
//! \sreturn The source part of the segment from which the dogleg has been created.
//! \function TrackElement* TrackElement::getTargetDogleg ();
//! \sreturn The target part of the segment from which the dogleg has been created.
//! \function TrackElements TrackElement::getPerpandiculars ();
//! \sreturn The collection of all element perpandiculars to this one.
//! \function void TrackElement::setFlags ( unsigned int flags );
//! Set to \true \c flags in the element state array.
//! \function void TrackElement::unsetFlags ( unsigned int flags );
//! Reset to \false \c flags in the element state array.
//! \function void TrackElement::setTrack ( Track* track );
//! Insert the element into \c track, also used as an insertion marker.
//! \function void TrackElement::setIndex ( size_t index );
//! Cache the element's index in the Track internal vector.
//! \function void TrackElement::updateFreedomDegree ();
//! Update, from the element characteristics, it's degree of freedom.
//! \function void TrackElement::setDoglegLevel ( unsigned int level );
//! Sets the level of dogleg of the element.
//! \function void TrackElement::swapTrack ( TrackElement* other );
//! Swap the tracks of \c this and \c other.
//! \function void TrackElement::reschedule ( unsigned int level );
//! If the TrackElement has already an event scheduled, change the
//! level of this event, otherwise create a new event.
//!
//! \sa NegotiateWindow::rescheduleEvent().
//! \function void TrackElement::detach ();
//! Remove the link from the TrackElement to it's owning Track, marking
//! it for removal. The removal from the Track's vector is managed by
//! the Track itself during the Session revalidation stage.
//! \function void TrackElement::revalidate ();
//! Actualize the TrackElement characteristics from the supporting
//! elements (set of AutoSegment).
//!
//! \red{Must be completed with the event management}
//! \function void TrackElement::invalidate ();
//! \sa AutoSegment::invalidate().
//! \function void TrackElement::incOverlapCost ( Net* net, TrackCost& cost ) const;
//! \sa Compute the cost of overlap between this segment and the interval
//! specified in \c cost. Mainly calls the relevant callback.
// \function void TrackElement::dataInvalidate ();
// Invalidate the algorithm datas.
// \function void TrackElement::eventInvalidate ();
// Invalidate the associated RoutingEvent (if any).
//! \function void TrackElement::setAxis ( DbU::Unit, unsigned int flags=Katabatic::SegAxisSet );
//! Sets the axis of the TrackElement.
//! \function TrackElement* TrackElement::makeDogleg ();
//! Create a dogleg on the source end of the TrackSegment. Put the dogleg
//! axis on the source \redB{To be further reviewed}.
//!
//! \sa \ref secDogleg "Dogleg management".
//!
//! Post-processing done by TrackSegment::_postDoglegs().
//! \function TrackElement* TrackElement::makeDogleg ( Katabatic::GCell* gcell );
//! \sa AutoSegment::makeDogleg(), \ref secDogleg "Dogleg management".
//!
//! Post-processing done by TrackSegment::_postDoglegs().
//! \function TrackElement* TrackElement::makeDogleg ( Interval interval, unsigned int& flags );
//! \sa AutoSegment::makeDogleg(), \ref secDogleg "Dogleg management", the return flags
//! from this method are returned through the \c flags variable.
//!
//! Post-processing done by TrackSegment::_postDoglegs().
//! \function bool TrackElement::_check () const;
//! Check the coherency of the element. For a TrackSegment:
//! - The supporting AutoSegment the canonical one of the set.
//! - The cached \c min & \c max values are identical to the computed
//! ones.
//!
//! \sreturn \true on success.
//! \function SegmentOverlapCostCB* TrackElement::setOverlapCostCB ( SegmentOverlapCostCB* cb );
//! \param cb the new overlap cost callback.
//! \return the previous overlap cost callback.
//!
//! sets the overlap callback.
/*! \class SegmentObserver
*
* \brief Observer on the base AutoSegment
*
* The observer that will be hooked into the observable in the associated
* canonical AutoSegment. Used to propagate the invalidation/revalidation
* events from AutoSegment toward TrackSegment.
*
* As a secondary function, it is used by the Session::lookup() method
* to quicly retrieve TrackSegment from Katabatic::AutoSegment.
*/
//! \function void SegmentObserver::notify ( unsigned int flags );
//! Implement the asymmetric invalidate/revalidate policy described in
//! Kite::Session. The invalidate is immediatly passed on while the
//! revalidate is ignored.
}

View File

@ -0,0 +1,29 @@
// -*- C++ -*-
#include "kite/TrackElement.h"
namespace Kite {
/*! \class TrackFixedSegment
* \brief Track elements for fixed wires.
*
* A TrackFixedSegment is a segment that cannot be moved from the
* track. It can be associated to a true blockage Segment (recognised
* by the fact that their owner net is the \e blockage net), or to
* a segment from an ordinary net but which is locked into position.
* In the latter case, the owned net may reuse this portion of the
* track if it needs it.
*
* In all cases, the blockage ratio of the GCells underneath the segment
* are updated.
*/
//! \function TrackSegment* TrackFixedSegment::create ( Track* track, Segment* segment );
//! \param segment The Hurricane Segment (blockage) to take into account.
//! \param track A Track into which insert the TrackFixedSegment.
//! \return A TrackFixedSegment wrapped around a blockage Segment.
//!
//! Public constructor to insert blockage inside a Track.
}

48
kite/doc/TrackMarker.dox Normal file
View File

@ -0,0 +1,48 @@
// -*- C++ -*-
namespace Kite {
/*! \class TrackMarker
* \brief Tag part of Track with a weight
*
* TrackMarkers are used to assign a cost on a span of Track
* telling how strongly a terminal is dependant on that Track
* to be accessed. The more Track a terminal crosses, the less
* the weight is.
*
* The weight is expressed in hundreth (can also be understood as
* percentage) of dependency over the Track. As example, if a
* terminal can only be accessed trough one Track is weight on
* it will be \c 100.
*/
//! \function TrackMarker::create ( RoutingPad* rp, size_t depth );
//! \param rp The RoutingPad to be accessed.
//! \param depth Select the layer depth by which we want to access
//! the RoutingPad.
//! \return The newly created TrackMarker.
//!
//! This constructor automatically take care of inserting the
//! TrackMarker in the relevant Tracks, so it must be called
//! during a Session.
//! \function Net* TrackMarker::getNet () const;
//! \sreturn The net of the RoutingPad.
//! \function DbU::Unit TrackMarker::getSourceU () const;
//! \sreturn The span minimum bound.
//! \function DbU::Unit TrackMarker::getTargetU () const;
//! \sreturn The span maximum bound.
//! \function Track* TrackMarker::getTrack () const;
//! \sreturn The Track into which the marker is inserted.
//! \function unsigned int TrackMarker::getWeight ( const Track* ) const;
//! \sreturn The associated weight, for now the Track argument is ignored.
//! \function void TrackMarker::setTrack ( Track* track );
//! Sets the owning Track.
}

View File

@ -0,0 +1,22 @@
// -*- C++ -*-
namespace Kite {
/*! \class VerticalTrack
* \brief Vertical track managment.
*/
//! \function bool VerticalTrack::isVertical () const;
//! \sreturn \false.
//! \function bool VerticalTrack::isVertical () const;
//! \sreturn \true.
//! \function unsigned int VerticalTrack::getDirection () const;
//! \sreturn Katabatic::KbVertical.
//! \function Point VerticalTrack::getPosition ( DbU::Unit position ) const;
//! \sreturn the point at \c (getAxis(),position).
}

798
kite/doc/asimbook.cls Normal file
View File

@ -0,0 +1,798 @@
%%
%% This is file `book.cls',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% classes.dtx (with options: `book')
%%
%% This is a generated file.
%%
%% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001
%% The LaTeX3 Project and any individual authors listed elsewhere
%% in this file.
%%
%% This file was generated from file(s) of the LaTeX base system.
%% --------------------------------------------------------------
%%
%% It may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.2
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%% http://www.latex-project.org/lppl.txt
%% and version 1.2 or later is part of all distributions of LaTeX
%% version 1999/12/01 or later.
%%
%% This file may only be distributed together with a copy of the LaTeX
%% base system. You may however distribute the LaTeX base system without
%% such generated files.
%%
%% The list of all files belonging to the LaTeX base distribution is
%% given in the file `manifest.txt'. See also `legal.txt' for additional
%% information.
%%
%% \CharacterTable
%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%% Digits \0\1\2\3\4\5\6\7\8\9
%% Exclamation \! Double quote \" Hash (number) \#
%% Dollar \$ Percent \% Ampersand \&
%% Acute accent \' Left paren \( Right paren \)
%% Asterisk \* Plus \+ Comma \,
%% Minus \- Point \. Solidus \/
%% Colon \: Semicolon \; Less than \<
%% Equals \= Greater than \> Question mark \?
%% Commercial at \@ Left bracket \[ Backslash \\
%% Right bracket \] Circumflex \^ Underscore \_
%% Grave accent \` Left brace \{ Vertical bar \|
%% Right brace \} Tilde \~}
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesClass{asimbook}
[2005/11/21 v1.0
ASIM LaTeX document class]
\newcommand\@ptsize{}
\newif\if@restonecol
\newif\if@titlepage
\@titlepagetrue
\newif\if@openright
\newif\if@mainmatter \@mainmattertrue
\if@compatibility\else
\DeclareOption{a4paper}
{\setlength\paperheight {297mm}%
\setlength\paperwidth {210mm}}
\DeclareOption{a5paper}
{\setlength\paperheight {210mm}%
\setlength\paperwidth {148mm}}
\DeclareOption{b5paper}
{\setlength\paperheight {250mm}%
\setlength\paperwidth {176mm}}
\DeclareOption{letterpaper}
{\setlength\paperheight {11in}%
\setlength\paperwidth {8.5in}}
\DeclareOption{legalpaper}
{\setlength\paperheight {14in}%
\setlength\paperwidth {8.5in}}
\DeclareOption{executivepaper}
{\setlength\paperheight {10.5in}%
\setlength\paperwidth {7.25in}}
\DeclareOption{landscape}
{\setlength\@tempdima {\paperheight}%
\setlength\paperheight {\paperwidth}%
\setlength\paperwidth {\@tempdima}}
\fi
\if@compatibility
\renewcommand\@ptsize{0}
\else
\DeclareOption{10pt}{\renewcommand\@ptsize{0}}
\fi
\DeclareOption{11pt}{\renewcommand\@ptsize{1}}
\DeclareOption{12pt}{\renewcommand\@ptsize{2}}
\if@compatibility\else
\DeclareOption{oneside}{\@twosidefalse \@mparswitchfalse}
\fi
\DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue}
\DeclareOption{draft}{\setlength\overfullrule{5pt}}
\if@compatibility\else
\DeclareOption{final}{\setlength\overfullrule{0pt}}
\fi
\DeclareOption{titlepage}{\@titlepagetrue}
\if@compatibility\else
\DeclareOption{notitlepage}{\@titlepagefalse}
\fi
\if@compatibility
\@openrighttrue
\else
\DeclareOption{openright}{\@openrighttrue}
\DeclareOption{openany}{\@openrightfalse}
\fi
\if@compatibility\else
\DeclareOption{onecolumn}{\@twocolumnfalse}
\fi
\DeclareOption{twocolumn}{\@twocolumntrue}
\DeclareOption{leqno}{\input{leqno.clo}}
\DeclareOption{fleqn}{\input{fleqn.clo}}
\DeclareOption{openbib}{%
\AtEndOfPackage{%
\renewcommand\@openbib@code{%
\advance\leftmargin\bibindent
\itemindent -\bibindent
\listparindent \itemindent
\parsep \z@
}%
\renewcommand\newblock{\par}}%
}
\ExecuteOptions{letterpaper,10pt,twoside,onecolumn,final,openright}
\ProcessOptions
\input{bk1\@ptsize.clo}
\setlength\lineskip{1\p@}
\setlength\normallineskip{1\p@}
\renewcommand\baselinestretch{}
\setlength\parskip{0\p@ \@plus \p@}
\@lowpenalty 51
\@medpenalty 151
\@highpenalty 301
\setcounter{topnumber}{2}
\renewcommand\topfraction{.7}
\setcounter{bottomnumber}{1}
\renewcommand\bottomfraction{.3}
\setcounter{totalnumber}{3}
\renewcommand\textfraction{.2}
\renewcommand\floatpagefraction{.5}
\setcounter{dbltopnumber}{2}
\renewcommand\dbltopfraction{.7}
\renewcommand\dblfloatpagefraction{.5}
%%%% Select Chapter font.
\newcommand \textchapter [1] {\textsf{\textbf{#1}}}
\newcommand \fontchapter {\sffamily \bfseries}
\if@twoside
\def\ps@headings{%
\let\@oddfoot\@empty\let\@evenfoot\@empty
\def\@evenhead{\thepage\hfil\slshape\leftmark}%
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
\let\@mkboth\markboth
\def\chaptermark##1{%
\markboth {\MakeUppercase{%
\ifnum \c@secnumdepth >\m@ne
\if@mainmatter
\@chapapp\ \thechapter. \ %
\fi
\fi
##1}}{}}%
\def\sectionmark##1{%
\markright {\MakeUppercase{%
\ifnum \c@secnumdepth >\z@
\thesection. \ %
\fi
##1}}}}
\else
\def\ps@headings{%
\let\@oddfoot\@empty
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
\let\@mkboth\markboth
\def\chaptermark##1{%
\markright {\MakeUppercase{%
\ifnum \c@secnumdepth >\m@ne
\if@mainmatter
\@chapapp\ \thechapter. \ %
\fi
\fi
##1}}}}
\fi
\def\ps@myheadings{%
\let\@oddfoot\@empty\let\@evenfoot\@empty
\def\@evenhead{\thepage\hfil\slshape\leftmark}%
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
\let\@mkboth\@gobbletwo
\let\chaptermark\@gobble
\let\sectionmark\@gobble
}
\if@titlepage
\newcommand\maketitle{\begin{titlepage}%
\let\footnotesize\small
\let\footnoterule\relax
\let \footnote \thanks
\null\vfil
\vskip 60\p@
\begin{center}%
{\LARGE \@title \par}%
\vskip 3em%
{\large
\lineskip .75em%
\begin{tabular}[t]{c}%
\@author
\end{tabular}\par}%
\vskip 1.5em%
{\large \@date \par}% % Set date in \large size.
\end{center}\par
\@thanks
\vfil\null
\end{titlepage}%
\setcounter{footnote}{0}%
\global\let\thanks\relax
\global\let\maketitle\relax
\global\let\@thanks\@empty
\global\let\@author\@empty
\global\let\@date\@empty
\global\let\@title\@empty
\global\let\title\relax
\global\let\author\relax
\global\let\date\relax
\global\let\and\relax
}
\else
\newcommand\maketitle{\par
\begingroup
\renewcommand\thefootnote{\@fnsymbol\c@footnote}%
\def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
\long\def\@makefntext##1{\parindent 1em\noindent
\hb@xt@1.8em{%
\hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
\if@twocolumn
\ifnum \col@number=\@ne
\@maketitle
\else
\twocolumn[\@maketitle]%
\fi
\else
\newpage
\global\@topnum\z@ % Prevents figures from going at top of page.
\@maketitle
\fi
\thispagestyle{plain}\@thanks
\endgroup
\setcounter{footnote}{0}%
\global\let\thanks\relax
\global\let\maketitle\relax
\global\let\@maketitle\relax
\global\let\@thanks\@empty
\global\let\@author\@empty
\global\let\@date\@empty
\global\let\@title\@empty
\global\let\title\relax
\global\let\author\relax
\global\let\date\relax
\global\let\and\relax
}
\def\@maketitle{%
\newpage
\null
\vskip 2em%
\begin{center}%
\let \footnote \thanks
{\LARGE \@title \par}%
\vskip 1.5em%
{\large
\lineskip .5em%
\begin{tabular}[t]{c}%
\@author
\end{tabular}\par}%
\vskip 1em%
{\large \@date}%
\end{center}%
\par
\vskip 1.5em}
\fi
\newcommand*\chaptermark[1]{}
\setcounter{secnumdepth}{2}
\newcounter {part}
\newcounter {chapter}
\newcounter {section}[chapter]
\newcounter {subsection}[section]
\newcounter {subsubsection}[subsection]
\newcounter {paragraph}[subsubsection]
\newcounter {subparagraph}[paragraph]
\renewcommand \thepart {\@Roman\c@part}
\renewcommand \thechapter {\@arabic\c@chapter}
\renewcommand \thesection {\thechapter.\@arabic\c@section}
\renewcommand\thesubsection {\thesection.\@arabic\c@subsection}
\renewcommand\thesubsubsection{\thesubsection .\@arabic\c@subsubsection}
\renewcommand\theparagraph {\thesubsubsection.\@arabic\c@paragraph}
\renewcommand\thesubparagraph {\theparagraph.\@arabic\c@subparagraph}
\newcommand\@chapapp{\chaptername}
\newcommand\frontmatter{%
\cleardoublepage
\@mainmatterfalse
\pagenumbering{roman}}
\newcommand\mainmatter{%
\cleardoublepage
\@mainmattertrue
\pagenumbering{arabic}}
\newcommand\backmatter{%
\if@openright
\cleardoublepage
\else
\clearpage
\fi
\@mainmatterfalse}
\newcommand\part{%
\if@openright
\cleardoublepage
\else
\clearpage
\fi
\thispagestyle{plain}%
\if@twocolumn
\onecolumn
\@tempswatrue
\else
\@tempswafalse
\fi
\null\vfil
\secdef\@part\@spart}
\def\@part[#1]#2{%
\ifnum \c@secnumdepth >-2\relax
\refstepcounter{part}%
\addcontentsline{toc}{part}{\thepart\hspace{1em}#1}%
\else
\addcontentsline{toc}{part}{#1}%
\fi
\markboth{}{}%
{\centering
\interlinepenalty \@M
\normalfont
\ifnum \c@secnumdepth >-2\relax
\huge\bfseries \partname\nobreakspace\thepart
\par
\vskip 20\p@
\fi
\Huge \bfseries #2\par}%
\@endpart}
\def\@spart#1{%
{\centering
\interlinepenalty \@M
\normalfont
\Huge \bfseries #1\par}%
\@endpart}
\def\@endpart{\vfil\newpage
\if@twoside
\if@openright
\null
\thispagestyle{empty}%
\newpage
\fi
\fi
\if@tempswa
\twocolumn
\fi}
\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
\thispagestyle{plain}%
\global\@topnum\z@
\@afterindentfalse
\secdef\@chapter\@schapter}
\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
\if@mainmatter
\refstepcounter{chapter}%
\typeout{\@chapapp\space\thechapter.}%
\addcontentsline{toc}{chapter}%
{\protect\numberline{\thechapter}#1}%
\else
\addcontentsline{toc}{chapter}{#1}%
\fi
\else
\addcontentsline{toc}{chapter}{#1}%
\fi
\chaptermark{#1}%
\addtocontents{lof}{\protect\addvspace{10\p@}}%
\addtocontents{lot}{\protect\addvspace{10\p@}}%
\if@twocolumn
\@topnewpage[\@makechapterhead{#2}]%
\else
\@makechapterhead{#2}%
\@afterheading
\fi}
%%%%\def\@makechapterhead#1{%
%%%% \vspace*{50\p@}%
%%%% {\parindent \z@ \raggedright \normalfont
%%%% \ifnum \c@secnumdepth >\m@ne
%%%% \if@mainmatter
%%%% \huge\bfseries \@chapapp\space \thechapter
%%%% \par\nobreak
%%%% \vskip 20\p@
%%%% \fi
%%%% \fi
%%%% \interlinepenalty\@M
%%%% \Huge \bfseries #1\par\nobreak
%%%% \vskip 40\p@
%%%% }}
\newlength \titlewidth
\setlength \titlewidth {\textwidth}
\addtolength \titlewidth {\marginparwidth}
\addtolength \titlewidth {\marginparsep}
\def\@makechapterhead#1{%
\vspace*{50\p@}%
{\parindent \z@ \raggedleft \fontchapter
\ifnum \c@secnumdepth >\m@ne
\if@mainmatter
\huge \@chapapp\space \thechapter
\par\nobreak
\vskip 20\p@
\fi
\fi
\interlinepenalty\@M
\hsize=\titlewidth
\Huge #1 \par\nobreak
\hsize=\textwidth
\vskip 40\p@
}}
\def\@schapter#1{\if@twocolumn
\@topnewpage[\@makeschapterhead{#1}]%
\else
\@makeschapterhead{#1}%
\@afterheading
\fi}
%%%%\def\@makeschapterhead#1{%
%%%% \vspace*{50\p@}%
%%%% {\parindent \z@ \raggedright
%%%% \normalfont
%%%% \interlinepenalty\@M
%%%% \Huge \bfseries #1\par\nobreak
%%%% \vskip 40\p@
%%%% }}
\def\@makeschapterhead#1{%
\vspace*{50\p@}%
{\parindent \z@ \raggedright
\normalfont
\interlinepenalty\@M
\hsize=\titlewidth
\flushright
\Huge \bfseries #1\par\nobreak
\hsize=\textwidth
\vskip 40\p@
}}
\newcommand\section{\@startsection {section}{1}{\z@}%
{-3.5ex \@plus -1ex \@minus -.2ex}%
{2.3ex \@plus.2ex}%
{\normalfont\Large\bfseries}}
\newcommand\subsection{\@startsection{subsection}{2}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{1.5ex \@plus .2ex}%
{\normalfont\large\bfseries}}
\newcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{1.5ex \@plus .2ex}%
{\normalfont\normalsize\bfseries}}
\newcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
{3.25ex \@plus1ex \@minus.2ex}%
{-1em}%
{\normalfont\normalsize\bfseries}}
\newcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}%
{3.25ex \@plus1ex \@minus .2ex}%
{-1em}%
{\normalfont\normalsize\bfseries}}
\if@twocolumn
\setlength\leftmargini {2em}
\else
\setlength\leftmargini {2.5em}
\fi
\leftmargin \leftmargini
\setlength\leftmarginii {2.2em}
\setlength\leftmarginiii {1.87em}
\setlength\leftmarginiv {1.7em}
\if@twocolumn
\setlength\leftmarginv {.5em}
\setlength\leftmarginvi {.5em}
\else
\setlength\leftmarginv {1em}
\setlength\leftmarginvi {1em}
\fi
\setlength \labelsep {.5em}
\setlength \labelwidth{\leftmargini}
\addtolength\labelwidth{-\labelsep}
\@beginparpenalty -\@lowpenalty
\@endparpenalty -\@lowpenalty
\@itempenalty -\@lowpenalty
\renewcommand\theenumi{\@arabic\c@enumi}
\renewcommand\theenumii{\@alph\c@enumii}
\renewcommand\theenumiii{\@roman\c@enumiii}
\renewcommand\theenumiv{\@Alph\c@enumiv}
\newcommand\labelenumi{\theenumi.}
\newcommand\labelenumii{(\theenumii)}
\newcommand\labelenumiii{\theenumiii.}
\newcommand\labelenumiv{\theenumiv.}
\renewcommand\p@enumii{\theenumi}
\renewcommand\p@enumiii{\theenumi(\theenumii)}
\renewcommand\p@enumiv{\p@enumiii\theenumiii}
\newcommand\labelitemi{\textbullet}
\newcommand\labelitemii{\normalfont\bfseries \textendash}
\newcommand\labelitemiii{\textasteriskcentered}
\newcommand\labelitemiv{\textperiodcentered}
\newenvironment{description}
{\list{}{\labelwidth\z@ \itemindent-\leftmargin
\let\makelabel\descriptionlabel}}
{\endlist}
\newcommand*\descriptionlabel[1]{\hspace\labelsep
\normalfont\bfseries #1}
\newenvironment{verse}
{\let\\\@centercr
\list{}{\itemsep \z@
\itemindent -1.5em%
\listparindent\itemindent
\rightmargin \leftmargin
\advance\leftmargin 1.5em}%
\item\relax}
{\endlist}
\newenvironment{quotation}
{\list{}{\listparindent 1.5em%
\itemindent \listparindent
\rightmargin \leftmargin
\parsep \z@ \@plus\p@}%
\item\relax}
{\endlist}
\newenvironment{quote}
{\list{}{\rightmargin\leftmargin}%
\item\relax}
{\endlist}
\if@compatibility
\newenvironment{titlepage}
{%
\cleardoublepage
\if@twocolumn
\@restonecoltrue\onecolumn
\else
\@restonecolfalse\newpage
\fi
\thispagestyle{empty}%
\setcounter{page}\z@
}%
{\if@restonecol\twocolumn \else \newpage \fi
}
\else
\newenvironment{titlepage}
{%
\cleardoublepage
\if@twocolumn
\@restonecoltrue\onecolumn
\else
\@restonecolfalse\newpage
\fi
\thispagestyle{empty}%
\setcounter{page}\@ne
}%
{\if@restonecol\twocolumn \else \newpage \fi
\if@twoside\else
\setcounter{page}\@ne
\fi
}
\fi
\newcommand\appendix{\par
\setcounter{chapter}{0}%
\setcounter{section}{0}%
\gdef\@chapapp{\appendixname}%
\gdef\thechapter{\@Alph\c@chapter}}
\setlength\arraycolsep{5\p@}
\setlength\tabcolsep{6\p@}
\setlength\arrayrulewidth{.4\p@}
\setlength\doublerulesep{2\p@}
\setlength\tabbingsep{\labelsep}
\skip\@mpfootins = \skip\footins
\setlength\fboxsep{3\p@}
\setlength\fboxrule{.4\p@}
\@addtoreset {equation}{chapter}
\renewcommand\theequation
{\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@equation}
\newcounter{figure}[chapter]
\renewcommand \thefigure
{\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@figure}
\def\fps@figure{tbp}
\def\ftype@figure{1}
\def\ext@figure{lof}
\def\fnum@figure{\figurename\nobreakspace\thefigure}
\newenvironment{figure}
{\@float{figure}}
{\end@float}
\newenvironment{figure*}
{\@dblfloat{figure}}
{\end@dblfloat}
\newcounter{table}[chapter]
\renewcommand \thetable
{\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@table}
\def\fps@table{tbp}
\def\ftype@table{2}
\def\ext@table{lot}
\def\fnum@table{\tablename\nobreakspace\thetable}
\newenvironment{table}
{\@float{table}}
{\end@float}
\newenvironment{table*}
{\@dblfloat{table}}
{\end@dblfloat}
\newlength\abovecaptionskip
\newlength\belowcaptionskip
\setlength\abovecaptionskip{10\p@}
\setlength\belowcaptionskip{0\p@}
\long\def\@makecaption#1#2{%
\vskip\abovecaptionskip
\sbox\@tempboxa{#1: #2}%
\ifdim \wd\@tempboxa >\hsize
#1: #2\par
\else
\global \@minipagefalse
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
\fi
\vskip\belowcaptionskip}
\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm}
\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf}
\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt}
\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf}
\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit}
\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl}
\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc}
\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal}
\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal}
\newcommand\@pnumwidth{1.55em}
\newcommand\@tocrmarg{2.55em}
\newcommand\@dotsep{4.5}
\setcounter{tocdepth}{2}
\newcommand\tableofcontents{%
\if@twocolumn
\@restonecoltrue\onecolumn
\else
\@restonecolfalse
\fi
\chapter*{\contentsname
\@mkboth{%
\MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
\@starttoc{toc}%
\if@restonecol\twocolumn\fi
}
\newcommand*\l@part[2]{%
\ifnum \c@tocdepth >-2\relax
\addpenalty{-\@highpenalty}%
\addvspace{2.25em \@plus\p@}%
\setlength\@tempdima{3em}%
\begingroup
\parindent \z@ \rightskip \@pnumwidth
\parfillskip -\@pnumwidth
{\leavevmode
\large \bfseries #1\hfil \hb@xt@\@pnumwidth{\hss #2}}\par
\nobreak
\global\@nobreaktrue
\everypar{\global\@nobreakfalse\everypar{}}%
\endgroup
\fi}
%%%%\newcommand*\l@chapter[2]{%
%%%% \ifnum \c@tocdepth >\m@ne
%%%% \addpenalty{-\@highpenalty}%
%%%% \vskip 1.0em \@plus\p@
%%%% \setlength\@tempdima{1.5em}%
%%%% \begingroup
%%%% \parindent \z@ \rightskip \@pnumwidth
%%%% \parfillskip -\@pnumwidth
%%%% \leavevmode \bfseries
%%%% \advance\leftskip\@tempdima
%%%% \hskip -\leftskip
%%%% #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
%%%% \penalty\@highpenalty
%%%% \endgroup
%%%% \fi}
\newcommand\l@chapter[2]{%
\ifnum \c@tocdepth >\m@ne
\addpenalty{-\@highpenalty}%
\vskip 1.0em \@plus\p@
\setlength\@tempdima{1.5em}%
\begingroup
\parindent \z@ \rightskip \@pnumwidth
\parfillskip -\@pnumwidth
\leavevmode \fontchapter
\advance\leftskip\@tempdima
\hskip -\leftskip
#1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
\penalty\@highpenalty
\endgroup
\fi}
\newcommand*\l@section{\@dottedtocline{1}{1.5em}{2.3em}}
\newcommand*\l@subsection{\@dottedtocline{2}{3.8em}{3.2em}}
\newcommand*\l@subsubsection{\@dottedtocline{3}{7.0em}{4.1em}}
\newcommand*\l@paragraph{\@dottedtocline{4}{10em}{5em}}
\newcommand*\l@subparagraph{\@dottedtocline{5}{12em}{6em}}
\newcommand\listoffigures{%
\if@twocolumn
\@restonecoltrue\onecolumn
\else
\@restonecolfalse
\fi
\chapter*{\listfigurename}%
\@mkboth{\MakeUppercase\listfigurename}%
{\MakeUppercase\listfigurename}%
\@starttoc{lof}%
\if@restonecol\twocolumn\fi
}
\newcommand*\l@figure{\@dottedtocline{1}{1.5em}{2.3em}}
\newcommand\listoftables{%
\if@twocolumn
\@restonecoltrue\onecolumn
\else
\@restonecolfalse
\fi
\chapter*{\listtablename}%
\@mkboth{%
\MakeUppercase\listtablename}%
{\MakeUppercase\listtablename}%
\@starttoc{lot}%
\if@restonecol\twocolumn\fi
}
\let\l@table\l@figure
\newdimen\bibindent
\setlength\bibindent{1.5em}
\newenvironment{thebibliography}[1]
{\chapter*{\bibname}%
\@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}%
\list{\@biblabel{\@arabic\c@enumiv}}%
{\settowidth\labelwidth{\@biblabel{#1}}%
\leftmargin\labelwidth
\advance\leftmargin\labelsep
\@openbib@code
\usecounter{enumiv}%
\let\p@enumiv\@empty
\renewcommand\theenumiv{\@arabic\c@enumiv}}%
\sloppy
\clubpenalty4000
\@clubpenalty \clubpenalty
\widowpenalty4000%
\sfcode`\.\@m}
{\def\@noitemerr
{\@latex@warning{Empty `thebibliography' environment}}%
\endlist}
\newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em}
\let\@openbib@code\@empty
\newenvironment{theindex}
{\if@twocolumn
\@restonecolfalse
\else
\@restonecoltrue
\fi
\columnseprule \z@
\columnsep 35\p@
\twocolumn[\@makeschapterhead{\indexname}]%
\@mkboth{\MakeUppercase\indexname}%
{\MakeUppercase\indexname}%
\thispagestyle{plain}\parindent\z@
\parskip\z@ \@plus .3\p@\relax
\let\item\@idxitem}
{\if@restonecol\onecolumn\else\clearpage\fi}
\newcommand\@idxitem{\par\hangindent 40\p@}
\newcommand\subitem{\@idxitem \hspace*{20\p@}}
\newcommand\subsubitem{\@idxitem \hspace*{30\p@}}
\newcommand\indexspace{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax}
\renewcommand\footnoterule{%
\kern-3\p@
\hrule\@width.4\columnwidth
\kern2.6\p@}
\@addtoreset{footnote}{chapter}
\newcommand\@makefntext[1]{%
\parindent 1em%
\noindent
\hb@xt@1.8em{\hss\@makefnmark}#1}
\newcommand\contentsname{Contents}
\newcommand\listfigurename{List of Figures}
\newcommand\listtablename{List of Tables}
\newcommand\bibname{Bibliography}
\newcommand\indexname{Index}
\newcommand\figurename{Figure}
\newcommand\tablename{Table}
\newcommand\partname{Part}
\newcommand\chaptername{Chapter}
\newcommand\appendixname{Appendix}
\def\today{\ifcase\month\or
January\or February\or March\or April\or May\or June\or
July\or August\or September\or October\or November\or December\fi
\space\number\day, \number\year}
\setlength\columnsep{10\p@}
\setlength\columnseprule{0\p@}
\pagestyle{headings}
\pagenumbering{arabic}
\if@twoside
\else
\raggedbottom
\fi
\if@twocolumn
\twocolumn
\sloppy
\flushbottom
\else
\onecolumn
\fi
\endinput
%%
%% End of file `book.cls'.

View File

@ -0,0 +1,96 @@
<!-- -*- explicit-buffer-name: "customHierarchy.html<kite/doc>" -*- -->
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
<!-- $Id: customHierarchy.html,v 1.1 2007/09/15 13:10:12 jpc Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Kite Documentation</title>
<link href="SoC.css" rel="stylesheet" type="text/css">
</head>
<h1 id="pagetop" class="header">Kite Documentation</h1>
<center class="header">
<table class="header">
<tr><td><a href="customSummary.html">Summary</a>
<td><a href="namespaces.html">Namespaces</a>
<td><a href="customHierarchy.html">Class Hierarchy</a>
<td><a href="annotated.html">Classes</a>
<td><a href="functions.html">Member Index</a>
<!-- <td><a href="classes.html">Index2</a> -->
</table>
</center>
<br>
<hr>
<body>
<h1>Kite Synthetic Class Hierarchy</h1>
<br>
<p><b>The complete class hierarchy could be accessed <a href="hierarchy.html">here</a>.</b></p>
<p>All the classes below are in the <a href="namespaceKite.html">Kite</a> namespace.</p>
<p>The inheritance tree has been splitted/simplificated.</p>
<b>Legend :</b><br>
<pre class="fragment">
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="#pagetop">ClassA</a><td><b>&nbsp;&nbsp;<tt>ClassA</tt> is abstract</b></tr>
<tr><td width="70"><td class="normal"><a href="#pagetop">ClassB</a><td><b>&nbsp;&nbsp;<tt>ClassB</tt> is instanciable</b></tr>
</table>
</pre>
<br>
<h2 class="classHierarchy">Tracks</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="classKite_1_1TrackMarker.html">TrackMarker</a>
<tr><td width="70"><td class="virtual"><a href="classKite_1_1TrackElement.html">TrackElement</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="normal"><a href="classKite_1_1SegmentObserver.html">SegmentObserver</a>
<tr><td width="140"><td class="normal"><a href="classKite_1_1TrackSegment.html">TrackSegment</a>
<tr><td width="140"><td class="normal"><a href="classKite_1_1TrackFixedSegment.html">TrackFixedSegment</a>
</table>
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="classKite_1_1Track.html">Track</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="normal"><a href="classKite_1_1HorizontalTrack.html">HorizontalTrack</a>
<tr><td width="140"><td class="normal"><a href="classKite_1_1VerticalTrack.html">VerticalTrack</a>
</table>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingPlane.html">RoutingPlane</a>
</table>
<h2 class="classHierarchy">Algorithm</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="classKite_1_1DataNegociate.html">DataNegociate</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEvent_1_1Key.html">RoutingEvent::Key</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEvent.html">RoutingEvent</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEventQueue.html">RoutingEventQueue</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEventLoop.html">RoutingEventLoop</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEventHistory.html">RoutingEventHistory</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1Session.html">Session</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1NegociateWindow.html">NegociateWindow</a>
</table>
<br>
Transient Data Structures For RoutingEvent
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="classKite_1_1SegmentAction.html">SegmentAction</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1Manipulator.html">Manipulator</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1SegmentFsm.html">SegmentFsm</a>
</table>
<h2 class="classHierarchy">Kite Engine</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="namespaceKite.html">Kite</a>
<tr><td width="70"><td class="normal"><a href="classKite_1_1KiteEngine.html">KiteEngine</a>
</table>
<hr>
<table class="footer1">
<tr><td class="LFooter"><small>Customized Class Hierarchy</small>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a>
</table>
<table class="footer2">
<tr><td class="LFooter">Kite Documentation
<td class="RFooter"><small>Copyright &#169; 2008-2013 UPMC. All rights reserved</small>
</table>
</body>
</html>

View File

@ -0,0 +1,86 @@
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
<!-- $Id: customSummary.html,v 1.1 2007/09/15 13:10:13 jpc Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Kite Documentation</title>
<link href="SoC.css" rel="stylesheet" type="text/css">
</head>
<h1 class="header">Kite Documentation</h1>
<center class="header">
<table class="header">
<tr>
<td><a href="customSummary.html">Summary</a></td>
<td><a href="namespaces.html">Namespaces</a></td>
<td><a href="customHierarchy.html">Class Hierarchy</a></td>
<td><a href="annotated.html">Classes</a></td>
<td><a href="functions.html">Member Index</a></td>
<!-- <td><a href="classes.html">Index2</a></td> -->
</tr>
</table>
</center>
<br>
<hr>
<body>
<h1>Kite Documentation Summary</h1>
<br>
<p><b>The classical Doxygen module documentation could be accessed <a href="modules.html">here</a>.</b></p>
<!--
<h2>Katabatic Concepts (internal)</h2>
<ol>
<li><a class="el" href="group__buildRules.html">Rules for building wires.</a>
<br>Rules for building AutoContacts. Global/Locals AutoSegments.
<li><a class="el" href="group__loadGlobalRouting.html">Global Routing Loading.</a>
<br>How the Knik global routing is loaded into Katabatic data-base.
Details the wiring topologies used to complete the routing to the
terminals.
<li><a class="el" href="group__collapseCanonical.html">AutoSegment Collapse &amp; Canonical.</a>
<br>How to force alignment of AutoSegments.
<li><a class="el" href="group__layerAssign.html">Layer Assignment.</a>
<br>Simple strategy to put long wires on higher routing metals.
<li><a class="el" href="group__NetConstraints.html">Constraints Computations.</a>
<br>Compute the legal range of variation of each wire (note that the
constraints are stored on AutoContacts).
<li><a class="el" href="group__NetOptimals.html">AutoSegment Optimal Placement.</a>
<br>Compute the optimal range of variation of each wire.
<li><a class="el" href="group__katabaticSession.html">Katabatic Update Session Mechanism.</a>
<br>The Session mechanism for modifying the Katabatic data-base.
</ol>
-->
<h2>API documentations</h2>
<ul>
<li><b><a href="customHierarchy.html">Synthetic Class Hierarchy.</a></b>
<li><b><a href="hierarchy.html">Complete Class Hierarchy (doxygen).</a></b>
<li><b><a href="annotated.html">Class List (doxygen).</a></b>
<li><b><a href="classes.html">Class Index (doxygen).</a></b>
<li><b><a href="modules.html">Modules (raw concepts).</a></b>
<li><b><a href="functions.html">Member Functions Index (doxygen).</a></b>
<li><b><a href="namespaces.html">Namespaces (doxygen).</a></b>
</ul>
<br>
<h2>Developer's Notes</h2>
<ul>
<li><b><a href="pageNotes.html">Notes to myself.</a></b>
</ul>
<br>
<hr>
<table class="footer1">
<tr>
<td class="LFooter"><small>Customized Concepts (a.k.a. modules)</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr>
</table>
<table class="footer2">
<tr>
<td class="LFooter">Kite Documentation</td>
<td class="RFooter"><small>Copyright &#169; 2005-2013 LIP6. All rights reserved</small></td>
</tr>
</table>
</body>
</html>

196
kite/doc/notes.dox Normal file
View File

@ -0,0 +1,196 @@
// -*- C++ -*-
namespace Kite {
/*! \page pageNotes Notes
*
* \section Summary
*
* - \ref ssecVariousNotes "Various Things to Remeber"
* - \ref secPendingModifications "Pending Modifications"
* - \ref secModificationsHistory "Modifications History"
* - \ref ssecArchitectureChanges "Changes in the general architecture"
* - \ref ssecModificationsKiteEngine "Changes in KiteEngine class design"
* - \ref ssecModificationsDataNegociate "Changes in DataNegociate class design"
* - \ref ssecModificationsTrackElement "Changes in TrackElement class design"
* - \ref ssecModificationsTrackSegment "Changes in TrackSegment class design"
* - \ref ssecModificationsAutoSegment "Changes in AutoSegment class design"
* - \ref ssecModificationsAutoContact "Changes in AutoContact class design"
* - \ref ssecBugBusting "Bug Solving Memento"
* - \ref ssecNanoRoute "Evaluation with Cadence NanoRoute"
*
* \section ssecVariousNotes Various Things to Remember
*
* - <b>Determinism checking.</b> The trace level to get only determinism related
* log is \c 500. Each line for the determinism is prepended with 'Deter|',
* possible with some leading spaces.
*
* - The router only sees/manages the aligned segment sets (through a pseudo-
* decorator on their canonical segment). So the non-canonical segments
* and the contacts should not be handled at all at this level.
* - Do do confuse the Session::Event, events that modificate
* the state of the Kite database (insert, move or remove TrackSegment
* in Track) and the RoutingEvent class which request that a segment
* must be processed.
* - In the various processing method of RoutingEvent, when a TrackSegment
* can be inserted inside a Track a Session::Event is generated but
* no further RoutingEvent, this end the placement processus of
* segment (until it is ripped-up).
* - AutoSegment do not invalidate their S/T anchor contacts.
* - AutoContact invalidate their anchored upon AutoSegment.
* - Now that the Hurricane database is deterministic, the router
* seems to be likewise.
*
*
* \section secPendingModifications Pending Modifications
*
* - In SegmentAction::doAction(), completly disable the movement of
* TrackSegment on it's target Track axis. This should not be
* needed as, if the algorithm as worked correctly, the next time
* it's RoutingEvent is processed, the target Track will have a
* free space to insert into. Then the Track insertion will
* set the TrackSegment axis.
* - Has to complete the lazy evaluation of the TrackSegment / DataNegociate
* / RoutingEvent. There is still some redundancy when the key of
* the RoutingEvent is updated.
* - In AutoContact::updateTopology() & AutoContact::updateGeometry()
* we could avoid to systematically run through the Hooks to cache
* the connected segments. This can be done once at the first call
* of either method (whichever comes first) on the first revalidate.
* Afterwards the cache can be updated only by AutoContact::updateTopology().
* - The canonization is done in two places, directly on a set of aligneds
* AutoSegments through AutoSegment::canonize() and for the whole net
* Session::_canonize(), which is called after the initial creation and
* each time the topology is modificated. The later may be suppressed
* if we uses more intelligently the former, and gain some more speedup.
*
*
* \section secModificationsHistory Modifications History
*
* \subsection ssecArchitectureChanges Changes in the general architecture
*
* - <b>Lazy Update.</b> Update of DataNegociate and RoutingEvent
* are now delayed until the event is processed, and systematically
* done at this point. Thus, the explicit invalidation of those
* objects is no longer needed. The revalidation is no longer
* triggered by the revalidation of TrackSegment.
*
*
* \subsection ssecModificationsKiteEngine Changes in KiteEngine class design
*
* - Suppress the lookup table of Hurricane::Segment toward
* TrackSegment. Instead uses the Observer mecanism between
* Katabatic::AutoSegment and TrackSegment.
*
*
* \subsection ssecModificationsDataNegociate Changes in DataNegociate class design
*
* - Merge in the separate class \c Cost.
* - Suppress the \c SlackState::Desalignate, due to the simplificated
* structure of the AutoSegment/AutoContacts (no more collapseds, or
* forced alignements).
* - Displace the computation and caching of the perpandiculars and
* perpandicular free interval from RoutingEvent into DataNegociate.
* Allows code factorization with the attractors computation, and
* data size reduction as there is exaclty one DataNegociate but
* there may be more than one RoutingEvent for the same TrackSegment.
*
*
* \subsection ssecModificationsTrackElement Changes in TrackElement class design
*
* - Due to the simplificated structure of the Katabatic contacts
* (terminal, turn, vtee & htee), there's no longer collapsed
* AutoSegment or \e expandable contacts. The \b desalignate
* feature, relaxing constraints due to collapsed segments
* or contacts with more than three segments, is no longer
* implemented.
* \redB{Have to redevelop a method to break long segments linked}
* \redB{by HTee or VTee.}
*
*
* \subsection ssecModificationsTrackSegment Changes in TrackSegment class design
*
* - The method \c TrackSegment::_postModify() is merged with
* TrackSegment::_postDoglegs() as, in the context of TrackSegment
* the only used topological modifications goes through the creation
* of one or more dogleg.
*
*
* \subsection ssecModificationsAutoSegment Changes in AutoSegment class design
*
* - In AutoSegment::_makeDogleg(), update the local/global status
* of the involved AutoSegment and re-canonize only what is necessary.
* Thus, guarantee that the net's topology is still valid after this
* method call and no topological update is needed at Session level
* (should be \e much faster).
* In this method, the code sharing between AutoHorizontal and
* AutoVertical can still be increased (update mechanisms are
* identicals).
* - The \c id support is now also implemented at Hurricane level.
* We may choose to use as a replacement of the one already present
* in AutoSegment. But in that case, we at least must cache the
* id in the AutoSegment. So we will not gain in memory footprint,
* the only benefit would be to have coherent id number throughout
* all the tools, but the sequentiality will be lost (this may not
* be a big issue).
*
*
* \subsection ssecModificationsAutoContact Changes in AutoContact class design
*
* - In AutoSegment::invalidate(), no longer uses collection to
* walk through attached AutoSegment, directly uses the cache.
* Much simple and efficient as we exactly know what is attached
* on every kind of contact.
*
*
* \section ssecBugBusting Bug Solving Memento
*
* <b>LUT lookup change:</b> When breaking a TrackSegment, the break may
* not occurs in the associated canonical AutoSegment. In that case the
* <code>dogleg[O]</code> will not match the one that is looked up
* for the broken (canonical) segment. Thus it was not a bug but a
* misunderstanding...
*
* <b>Overlap of perpandiculars after a dogleg creation:</b>
* The axis of the new parallel was not set to the axis of it's parent.
* This was due to the uses of AutoSegment::setAxis() in
* AutoHorizontal::_makeDogleg() which silently
* do nothing on non-canonical AutoSegment, and at this point, the
* re-canonisation did not yet take place. Now Uses AutoSegment::_setAxis()
* the atomic variant wich works inconditionnaly.
*
*
* \section ssecNanoRoute Evaluation with Cadence NanoRoute
*
* To perform a comparison with NanoRoute the procedure is as follow:
*
* - Export the design in Alliance \c DEF format. It will generate both
* \c DEF file and the supporting \c LEF file containing the technology
* and the abstract of all the standard cell of the design.
* As Alliance uses symbolic units (lambda), they are translated with
* the simple rule: <b>1 lambda == 1 micron</b>.
*
* - Run the commands in NanoRoute:
* - <tt>loadLefFile design.lef</tt>
* - <tt>loadDefFile design.def</tt>
* - <tt>generateTracks</tt>
* - <tt>generateVias</tt>
* - <tt>setNanoRouteMode -quiet -drouteFixAntenna 0</tt>
* - <tt>setNanoRouteMode -quiet -drouteStartIteration default</tt>
* - <tt>setNanoRouteMode -quiet -routeTopRoutingLayer default</tt>
* - <tt>setNanoRouteMode -quiet -routeBottomRoutingLayer 2</tt>
* - <tt>setNanoRouteMode -quiet -drouteEndIteration default</tt>
* - <tt>setNanoRouteMode -quiet -routeWithTimingDriven false</tt>
* - <tt>setNanoRouteMode -quiet -routeWithSiDriven false</tt>
* - <tt>routeDesign -globalDetail</tt>
*
* - To perform as fair a comparison as possible, those commands disable
* antenna effect protection and disable the use of the \c M1 as a
* routing layer (<tt>-routeBottomRoutingLayer 2</tt>). Those commands
* are issued through the graphical interface of NanoRoute.
*
* <em>To see the resulting layout, do not forget to switch the view mode.</em>
*/
}