diff --git a/kite/doc/Constants.dox b/kite/doc/Constants.dox new file mode 100644 index 00000000..7381949e --- /dev/null +++ b/kite/doc/Constants.dox @@ -0,0 +1,36 @@ + // -*- mode: C++; explicit-buffer-name: "Constants.h" -*- + + 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. + + } diff --git a/kite/doc/DataNegociate.dox b/kite/doc/DataNegociate.dox new file mode 100644 index 00000000..d0073bfb --- /dev/null +++ b/kite/doc/DataNegociate.dox @@ -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. + * + * State related datas: + * - 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. + * + * Topological related datas: + * - \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 wiring delta 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: + //! (state<<4)+ripup. + + //! \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. + + } diff --git a/kite/doc/HorizontalTrack.dox b/kite/doc/HorizontalTrack.dox new file mode 100644 index 00000000..a97777ee --- /dev/null +++ b/kite/doc/HorizontalTrack.dox @@ -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()). + + } diff --git a/kite/doc/KiteEngine.dox b/kite/doc/KiteEngine.dox new file mode 100644 index 00000000..5d6b95de --- /dev/null +++ b/kite/doc/KiteEngine.dox @@ -0,0 +1,55 @@ + + // -*- C++ -*- + + namespace Kite { + + /*! \class KiteEngine + * + * \brief The Kite Tool + * + * Lookup Mechanism + * + * 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 per se 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. + + } diff --git a/kite/doc/Manipulator.dox b/kite/doc/Manipulator.dox new file mode 100644 index 00000000..a4c0da87 --- /dev/null +++ b/kite/doc/Manipulator.dox @@ -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. + * + * The TrackElement may differs from the one of the SegmentFsm. + * This can occurs when manipulating perpandiculars or segments from + * other nets in conflict. For example: Manipulator::isCaged(). + * + * In the following documentation, the segment which is associated + * to the SegmentFsm will be called the reference segment. + * + * \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. + + } diff --git a/kite/doc/NegociateWindow.dox b/kite/doc/NegociateWindow.dox new file mode 100644 index 00000000..90ecdb83 --- /dev/null +++ b/kite/doc/NegociateWindow.dox @@ -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. + + } diff --git a/kite/doc/RoutingEvent-old.dox b/kite/doc/RoutingEvent-old.dox new file mode 100644 index 00000000..031e85e6 --- /dev/null +++ b/kite/doc/RoutingEvent-old.dox @@ -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 + *
  • New \c isLocal() method on \TrackSegment. Tells if the \TrackSegment + * is associated only to local AutoSegment. + *
  • Increase the overlap cost of a \TrackSegment from an already routed + * GCell routing set. + * + * + * + * \section secRoutingEventInterval The various intervals of a RoutingEvent + * + * The three Intervals controlling a RoutingEvent : all those intervals + * defines the track range in which the \TrackSegment could be inserted. + *
      + *
    • The optimal interval : where the \Net wirelength will be + * minimal (comes from \c Katabatic::AutoSegment). + *
    • The constraint 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). + *
    • The perpandicular 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. + *
    + * The perpandicular interval comes from perpandicular constraints on \TrackSegment + * of the same \c Net. The left/right axis weights comes from requests of + * other \c Nets. + * + * \image html RoutingEvent-1.png "RoutingEvent Intervals" + * \image latex RoutingEvent-1.pdf "RoutingEvent Intervals" width=0.6\textwidth + * + * Example of perpandicular interval computation : + * + * \image html RoutingEvent-2.png "Perpandicular Interval" + * \image latex RoutingEvent-2.pdf "Perpandicular Interval" + * + * + * \section secRoutingEventRules Rules governing RoutingEvents + * + * \RoutingEvent respect the following rules: + *
      + *
    • A \TrackSegment can only be displaced by it's associated \RoutingEvent. + *
    • Corollary: the only \TrackSegment displaced while processing a + * \RoutingEvent is the one associated to the event. + *
    • Conflicts occurs between the \RoutingEvent \TrackSegment and already + * placed others \TrackSegment. + * + * The conflict can be solved by displacing/modifying others + * \TrackSegment or by modifying the to be inserted one. In the later + * case, the newly created or modified \TrackSegment are (re)scheduleds + * before the would be inserted. + *
    • 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. + *
    • \TrackSegment are inserted only, and only if there is enough free space. + * That is, if any kind of overlap occurs, it is not inserted + * but rescheduled. The blocking \TrackSegments are then + * rescheduled after the current one. + *
    • Each \RoutingEvent processing takes place inside a one atomic + * Session. That is, the coherency of the data-base is restored + * immediatly afterward (both Kite & Katabatic). + *
    + * + * \remark Be very careful to distinguish between Session commands, which affects + * \Track and \TrackSegment insertion/update/removal and schedule/re-schedule + * events, which relates to the negociation algorithm. + * + * Re-ordering rules: + *
      + *
    1. In normal mode, that is, no maximum ripup has been reached, the + * blocking other \TrackSegment are removed and the current + * is rescheduled before them. + *
    2. In maximum ripup mode, some \TrackSegment has to give way. + *
        + *
      • If the current one is modified, it must be rescheduled after + * it's modified bits are rescheduleds. + *
      • If others are modifieds they must be rescheduled after + * the current one (so it will grabs the place). + *
      + *
    + * + * + * \section secRoutingEventCycle RoutingEvent life cycle + * + * As an active \RoutingEvent is associated with one and only one \TrackSegment + * we can talk indeferently of \RoutingEvent lifecycle or \TrackSegment + * lifecycle. + * + * Below is the ordered list of states that a \RoutingEvent could be in. + * The order correspond to increasing level of slackening/freedom. + * Transition between states occurs each time a maximum ripup is reached. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
     \b Id \b Type \b Local  \b Global \b Action
    \e 1\c Minimize\e yes\e notry to fit into a hole
    \e 2\c DogLeg\e yes\e noDogleg : analyse overlap and try to solve it by breaking (self)
    \e 3\c Desalignate\e yes\e yeson a set of alignated \TrackSegment, suppress the + * alignment constraints, thus making then independants + *
    \e 4\c Slacken\e yes\e yesif the target/source constraint is less than the + * GCell, adds perpandicular straps to free the \TrackSegment. + * This occurs to free from terminal constraints + *
    \e 5\c ConflictSolve1\e yes\e yestry to find in the history a reccurent dislodger, + * and break (self) to accomodate it + *
    \e 6\c ConflictSolve2\e no\e yestry to find a Track on which we can dislodge + * an other \TrackSegment + *
    \e 7\c MoveUp\e no\e yestry to go on upper layer. + *
    \e 8\c Unimplemented\e no\e yeswe failed to place this \TrackSegment + *
    + * + * + * \section secManageMaximumRipup Managing the maximum ripup case + * +\code +bool State::manageMaximumRipup () +{ + bool success = false; + + if ( !_segment->isGlobal() ) { + // Candidates Tracks (ignore optimal & perpandiculars). + candidates = computeAllIntervals (); + overlap = _segment->getInterval(); + + for ( size_t i=0 ; i reject. + // Local vs. Terminal => reject. + if ( others[0]->isLocal() || others[0]->isTerminal() ) continue; + + // Local vs. Global (not routed yet). + if ( others[i]->getOrder() >= _segment->getOrder() ) { + success = modifyTopology(others[0]); + break; + } + + // Local vs. Global (already routed). + success = relax(_others[0],overlap); + if ( success ) break; + } + } + } + + if ( !success ) { + // Global vs. Local. + // Failed Local vs. Any. + success = modifyTopology(_segment); + } + return success; +} +\endcode + * + * + * \section secModifyTopology Description of the modifyTopology() method + * +\code +bool Manipulator::modifyTopology ( TrackSegment* segment ) +{ + bool success = false; + + if ( segment->isLocal() ) { + if ( segment->canMinimize() { + segment->minimize(); + success = true; + } + if ( segment->canDogLeg() ) { + // Case -C.4- "Self Relax". + segment->makeDogLeg(); + success = true; + } + } else if ( segment->canDesalignate() ) { + // Case -C.5- "Desalignate". + segment->desalignate(); + success = true; + } else if ( segment->canSlacken() ) { + // Case -C.6- "Slacken". + segment->slacken(); + success = true; + } else { + RipupHistory* history = RipupHistory(segment); + GCell* dogLegGCell = history.getDogLegGCell(); + + if ( dogLegGCell ) { + if ( segment->canDogLegAt(dogLegGCell) ) { + segment->makeDogLeg(dogLegGCell) + success = true; + } + } else { + // Dislodgers seems to far in ripup history. + // Recheck the Track, maybe they have vanish. + Track* track = getTrack(segment); + if ( track->getFreeInterval(segment) ) { + track.insert ( segment ); + success = true; + } + } + } + + if ( segment->canMoveUp() ) { + segment->moveUp (); + success = true; + } + + if ( success ) { + resetRipupCount(segment); + } else { + cerr << "[UNIMPLEMENTED] " << segment << endl; + } + + return success; +} +\endcode + * + * + * \section secHardSoftOverlap Hard and soft overlap + * + * Schematic execution of a \RoutingEvent leading to a set aside. + *
      + *
    1. The scheduler try to place the \TrackSegment on top of the + * event queue, calling process(). + *
    2. There is a soft overlap on the best candidate track, a set + * aside is issued. + *
    3. Each \TrackSegment in conflict in the candidate track has the + * \RoutingEvent bounds of it's perpandicular \TrackSegment modificated + * according to the free space requested through setLeftBound() or setRightBound(). + *
    4. If a perpandicular is already in a \Track is removed from it and scheduled for + * immediate re-routing (it's event level is increased so it pops + * out immediately from the queue). + *
    5. If the perpandicular is not routed yet, we are done. + * + * Note that this technique of modificating a \RoutingEvent yet to come is + * kind a like seeing the future... + *
    + * + * \image html RoutingEvent-3.png "Set aside schematic" + * \image latex RoutingEvent-3.pdf "Set aside schematic" + * + * + * \section setDetructionStrategy Destruction Strategy + * + * \RoutingEvent are not destroyed as soon as they have been processed by + * the scheduler. Instead, they are stored in the historical queue. + * They are two reasons for that behavior : + *
      + *
    • \RoutingEvent are used to store algorithmic informations that + * must persist until the negociation algorithm have fully + * completed (bound interval in particular). + *
    • When ripup phases takes place and maximum ripup count is + * reached, the history can be used to find the whole set of + * \TrackSegment in conflict an made an educated guess about + * which one must be relaxed. + *
    + * + * \important This is the history queue which is responsible for freeing all the + * \RoutingEvent in his destructor. + * + * + * \section secRoutingEventCase Routing Event actions + * + *
      + *
    • Free Track Case + * + * There is a sufficent free space in the candidate \Track to insert the + * \TrackSegment. The \TrackSegment is inserted. + * + * \important This is the only way for a \TrackSegment to be inserted into a \Track. + * + * \image html RoutingEvent-10.png + * \image latex RoutingEvent-10.pdf + * + * + *
    • Soft Overlap Case + * + * Already inserted \TrackSegment a & b could be shrunk + * to make place for \TrackSegment c. Parallel overlaping \TrackSegment + * are not removed, their perpandiculars are with updated left/right axis weight. + * + * The a perpandicular belongs the same GCell routing set so it + * is removed from is \Track to be displaced. + * + * The b perdandicular belongs to a more prioritary GCell routing + * set, which has therefore be placed earlier so it can't be removed. + * Instead it is broken. + * + * \image html RoutingEvent-11.png + * \image latex RoutingEvent-11.pdf + * + * + *
    • Hard Overlap Case + * + * No way to shrunk overlaping \TrackSegment to make place for c. + * All parallel overlaping \TrackSegments must be removeds to be displaced + * on other \Tracks. + * + * The a parallel belongs to a more prioritary GCell routing set + * so it can be removed, it is therefore broken. + * + * The b parallel belongs the same GCell routing set so it can be + * removed to be displaced. + * + * \image html RoutingEvent-12.png + * \image latex RoutingEvent-12.pdf + * + * + *
    • Self Relax + * + * Instead of trying to displace overlaping \TrackSegments we break the + * current one. + * + * \image html RoutingEvent-13.png + * \image latex RoutingEvent-13.pdf + * + * + *
    • Self Desalignate + * + * Instead of trying to displace overlaping \TrackSegments we desalignate + * it's components (by supressing alignement constraints on it's + * AutoContacts). We do not create new Katabatic components but new + * \TrackSegments will appears. + * + * \image html RoutingEvent-14.png + * \image latex RoutingEvent-14.pdf + * + * + *
    • Self Slacken + * + * Instead of trying to displace overlaping \TrackSegments we slacken + * the current one. This is different than desalignate because we create + * new Katabatic component to relax any AutoContact transmitted constraints. + * This operation is most likely to be applied on \TrackSegments that are + * directly connecteds to terminals. + * + * \image html RoutingEvent-15.png + * \image latex RoutingEvent-15.pdf + * + *
    + */ + + /*! \function bool RoutingEvent::isProcessed () const; + * \return \true if this event has already been processed. + * + * \remark Note that inside a _setAside() a \RoutingEvent can be re-posted for + * a given \TrackSegment which has been processed yet. This can lead + * to two or more \RoutingEvent in the queue (as we cannot easily remove + * a \RoutingEvent already in the queue). We need this new \RoutingEvent + * because we want to reschedule with a new priority/slack. + * As we cannot remove the previous \RoutingEvent, we mark it as + * processed for it to be ignored by the scheduler. + */ + + /*! \function TrackSegment* RoutingEvent::getSegment () const; + * \Return The associated and unique \TrackSegment. + */ + + /*! \function unsigned long RoutingEvent::getPriority () const; + * \Return The second criterion used to sort \RoutingEvents in the negociation queue. + * Currently, it is the area of the associated \TrackSegment, which in + * turn return the slack (not a very fortunate choice of name...). + */ + + /*! \function unsigned int RoutingEvent::getEventLevel () const; + * \Return The first criterion used to sort \RoutingEvents in the negociation queue. + * It is used to re-schedule a \RoutingEvent and make the new event be + * processed before the original one, which is marked as + * processed to be ignored. + * + * \see setEventLevel(). + */ + + /*! \function RoutingEvent* RoutingEvent::getClone () const; + * \Return An exact copy of the current \RoutingEvent. + */ + + /*! \function RoutingEvent* RoutingEvent::reschedule ( RoutingEventQueue& queue ); + * \param queue The \RoutingEvent queue. + * \return The rescheduled \RoutingEvent. May be \NULL if it cannot be rescheduled. + */ + + /*! \function void RoutingEvent::setProcessed ( bool state=true ); + * \param state The state into which the event is to be put. + * + * Mark the event as processed. This arises in two cases : + *
      + *
    • The event has really been processed by the process() member + * function. + *
    • There has been a fork from this event and it has been + * superseded by a newly rescheduled one, so we have to + * invalidate this one. + *
    + */ + + /*! \function void RoutingEvent::setEventLevel ( unsigned int level ); + * \param level The new event level. + * + * \see getEventLevel(). + */ + + /*! \function void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history ); + * \param queue The event queue from the negociate algorithm. + * \param history The event history. + * + * Perform all the operations shared by all \RoutingEvent classes then + * calls the virtual _subProcess() functions. + * + * Shared operations are : + *
      + *
    1. Invalidating all perpandicular \TrackSegments. + *
    2. Computing the free interval allowed by the free intervals + * in perpandicular \Tracks holding the perpandicular \TrackSegments. + *
    3. Merging in the various constraints intervals : from the + * \TrackSegment itself, from the free intervals in the + * perpandicular \Tracks and from the \RoutingEvent bound + * constraints. + *
    4. Finding the candidate \Tracks for the \RoutingEvent, + * using \c Track_Spiral \Collection. + *
    + * The results of the shared operation are passed to derived classes + * trough the \c State internal structure. + */ + + /* \function bool RoutingEvent::_setAside ( Track* track, size_t begin, size_t end, Net* net, Interval interval, RoutingEventQueue& queue ); + * \param track The track in wich to make free space. + * \param begin The index of the first overlaping TrackSegment. + * \param end The index of the last overlaping TrackSegment. + * \param net The net for which we want to insert a TrackSegment. + * \param interval The interval which must be made empty. + * \param queue The queue of RoutingEvent. + * + * Manage the case of soft overlap. Create or enlarge a free space + * in \c track so it can contain the requested \interval. [begin:end] defines + * the range of indexes of overlaping \TrackSegment in \c track. + * Displace TrackSegment that are perpandicular to those overlaping, + * remove them from their \c Track if needed and issue an associated \RoutingEvent + * with an updated bound constraint. Note that the overlaping \TrackSegment + * themselves are not removed from the \c track. + * + * A note on implementation : + *
      + *
    • \c data1 : the DataNegociate of the to be inserted \TrackSegment. + *
    • \c segment2 : the current overlaping \TrackSegment (from \c begin + * to \c end). + *
    • \c data2 : the DataNegociate of the overlaping \TrackSegment. + *
    • \c segment3 : a \TrackSegment perpandicular to \c segment2. + *
    + */ + + /* \function void RoutingEvent::_ripup ( Track* track, Net* net, Interval interval, size_t begin, size_t end, RoutingEventQueue& queue ); + * \param track The track in wich to make free space. + * \param net The net for which we want to insert a TrackSegment. + * \param interval The interval which must be made empty. + * \param begin The index of the first overlaping TrackSegment. + * \param end The index of the last overlaping TrackSegment. + * \param queue The queue of RoutingEvent. + * + * Manage the case of hard overlap, that is bluntly remove + * any \TrackSegment overlaping \interval. Issue both a remove event + * (to \c Session) and a \RoutingEvent to re-process the dislodged + * \TrackSegment. + */ + + } // End of Kite namespace. diff --git a/kite/doc/RoutingEventHistory.dox b/kite/doc/RoutingEventHistory.dox new file mode 100644 index 00000000..6807cfe5 --- /dev/null +++ b/kite/doc/RoutingEventHistory.dox @@ -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. + + } diff --git a/kite/doc/RoutingEventLoop.dox b/kite/doc/RoutingEventLoop.dox new file mode 100644 index 00000000..a3de9edc --- /dev/null +++ b/kite/doc/RoutingEventLoop.dox @@ -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& 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. + + } diff --git a/kite/doc/RoutingEventQueue.dox b/kite/doc/RoutingEventQueue.dox new file mode 100644 index 00000000..891f0989 --- /dev/null +++ b/kite/doc/RoutingEventQueue.dox @@ -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. + * + * Insertion, Reinsertion & Commit + * + * 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. + * + * Mutiple Event for one Segment + * + * As RoutingEvent can be cloned, there may be more than one event pointing + * to a segment. But there must be only one active event, the one + * which is pointed to by the segment. As a result, there maybe multiple + * events for an unique segment in the queue, but only one active event, + * 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& ); + //! 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. + //! + //! No commit is needed after this operation. + + //! \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). + + } diff --git a/kite/doc/RoutingPlane.dox b/kite/doc/RoutingPlane.dox new file mode 100644 index 00000000..788bc0fe --- /dev/null +++ b/kite/doc/RoutingPlane.dox @@ -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 to create 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. + + + } diff --git a/kite/doc/SegmentFsm.dox b/kite/doc/SegmentFsm.dox new file mode 100644 index 00000000..9c692bd5 --- /dev/null +++ b/kite/doc/SegmentFsm.dox @@ -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 reference segment + //! 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
    + //! Action: The reference segment is to be inserted in a Track (placed).
    + //! Event Level: Unchanged. + //! + //! - SegmentAction::SelfRipup
    + //! Action: The reference segment is to be ripped up.
    + //! Event Level: Unchanged. + //! + //! - SegmentAction::SelfRipupPerpand
    + //! Action: 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.
    + //! Event Level: Unchanged. + //! + //! - SegmentAction::SelfRipupPerpandWithAxisHint
    + //! Action: 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.
    + //! Event Level: Increased to SegmentAction::EventLevel4. + //! + //! - SegmentAction::OtherRipup
    + //! Action: Ripping up a segment from another net and in the same direction + //! as the reference segment.
    + //! Event Level: Unchanged. + //! + //! - SegmentAction::OtherRipupPerpandAndPushAside
    + //! Action: 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.
    + //! Event Level: Increased to SegmentAction::EventLevel3. + //! + //! - SegmentAction::OtherRipupPerpandAndPacking
    + //! Action: 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.
    + //! Event Level: Increased to SegmentAction::EventLevel4. + + //! \var SegmentAction::Self + //! [Flag] The segment associated to the action is the reference segment + //! or segments from the same net. + + //! \var SegmentAction::Other + //! [Flag] The segment associated to the action is \b not from the same + //! net as the reference segment. + + //! \var SegmentAction::Perpandicular + //! [Flag] The action concern a perpandicular to the reference segment. + + //! \var SegmentAction::Ripup + //! [Flag] Request that the segment is to be ripped up. + + //! \var SegmentAction::RipedByLocal + //! [Flag] Indicate that the segment has been ripped up by a local one. + + //! \var SegmentAction::ResetRipup + //! [Flag] The ripup count is to be reset. + + //! \var SegmentAction::ToRipupLimit + //! [Flag] 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 + //! [Flag] 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 + //! [Flag] An axis hint has been supplied, and is to be passed to + //! the generated RoutingEvent. + + //! \var SegmentAction::PackingMode + //! [Flag] Whether the RoutingEvent should be processed in \e packing + //! mode or \e negociated mode (transmitted to the RoutingEvent). + + //! \var SegmentAction::ToState + //! [Flag] 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 + //! [Flag] Increase the level to at least \b 1. + + //! \var SegmentAction::EventLevel2 + //! [Flag] Increase the level to at least \b 2. + + //! \var SegmentAction::EventLevel3 + //! [Flag] Increase the level to at least \b 3. + + //! \var SegmentAction::EventLevel4 + //! [Flag] Increase the level to at least \b 4. + + //! \var SegmentAction::EventLevel5 + //! [Flag] Increase the level to at least \b 5. + + //! \var SegmentAction::SelfInsert + //! [Mask], see SegmentAction::Type. + + //! \var SegmentAction::SelfRipup + //! [Mask], see SegmentAction::Type. + + //! \var SegmentAction::SelfRipupPerpand + //! [Mask], see SegmentAction::Type. + + //! \var SegmentAction::SelfRipupPerpandWithAxisHint + //! [Mask], see SegmentAction::Type. + + //! \var SegmentAction::OtherRipup + //! [Mask], see SegmentAction::Type. + + //! \var SegmentAction::OtherRipupPerpandAndPushAside + //! [Mask], see SegmentAction::Type. + + //! \var SegmentAction::OtherRipupPerpandAndPacking + //! [Mask], 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 the first track + * candidate 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 + //! [Flag], see SegmentFsm::SegmentFsmValue. + + //! \var SegmentFsm::EmptyTrackList + //! [Flag], see SegmentFsm::SegmentFsmValue. + + //! \var SegmentFsm::Inserted + //! [Flag], the TrackElement can be inserted in a Track. + + //! \var SegmentFsm::Self + //! [Flag], the action is related to the processed TrackSegment. + + //! \var SegmentFsm::Other + //! [Flag], the action is \b not related to the processed TrackSegment, + //! that is, others are being topologically modificated or riped up. + + //! \var SegmentFsm::Ripup + //! [Flag], segement, that are not the processed one are being ripped up. + + //! \var SegmentFsm::MaximumSlack + //! [Flag], the processed segment as reached it's maximum ripup count on + //! the last possible slackening state. + + //! \var SegmentFsm::SelfInserted + //! [Mask], see SegmentFsm::SegmentFsmValue. + + //! \var SegmentFsm::OtherRipup + //! [Mask], see SegmentFsm::SegmentFsmValue. + + //! \var SegmentFsm::SelfMaximumSlack + //! [Mask], 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& 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& 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: (a), (b), (c) form a + //! first cluster and (d), (e), (f) 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 (g) 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" + //! + //! Dislodger Definition: + //! + //! 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. + //! + //! Synthetic Description + //! + //! -# 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: + //! - The dislodger is local, then try to relax the to placed + //! segment around the dislodger. + //! - The dislodger is global, 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). + //! + //! Interval Accounting + //! + //! 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. + //! + //! Track Ordering (lexicographic) + //! + //! -# 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. + + } diff --git a/kite/doc/SoC.css b/kite/doc/SoC.css new file mode 100644 index 00000000..276a7c09 --- /dev/null +++ b/kite/doc/SoC.css @@ -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; + } + diff --git a/kite/doc/TrackElement.dox b/kite/doc/TrackElement.dox new file mode 100644 index 00000000..e0c12e64 --- /dev/null +++ b/kite/doc/TrackElement.dox @@ -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. + * + * Design Note + * + * 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. + + } diff --git a/kite/doc/TrackFixedSegment.dox b/kite/doc/TrackFixedSegment.dox new file mode 100644 index 00000000..70a5febe --- /dev/null +++ b/kite/doc/TrackFixedSegment.dox @@ -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. + + } diff --git a/kite/doc/TrackMarker.dox b/kite/doc/TrackMarker.dox new file mode 100644 index 00000000..ce0f41eb --- /dev/null +++ b/kite/doc/TrackMarker.dox @@ -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. + + } diff --git a/kite/doc/VerticalTrack.dox b/kite/doc/VerticalTrack.dox new file mode 100644 index 00000000..21363fff --- /dev/null +++ b/kite/doc/VerticalTrack.dox @@ -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). + + } diff --git a/kite/doc/asimbook.cls b/kite/doc/asimbook.cls new file mode 100644 index 00000000..54270780 --- /dev/null +++ b/kite/doc/asimbook.cls @@ -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'. diff --git a/kite/doc/customHierarchy.html b/kite/doc/customHierarchy.html new file mode 100644 index 00000000..551fa1ee --- /dev/null +++ b/kite/doc/customHierarchy.html @@ -0,0 +1,96 @@ + + + + + + + Kite Documentation + + +

    Kite Documentation

    +
    + +
    Summary + Namespaces + Class Hierarchy + Classes + Member Index + +
    +
    +
    +
    + +

    Kite Synthetic Class Hierarchy

    +
    + +

    The complete class hierarchy could be accessed here.

    +

    All the classes below are in the Kite namespace.

    +

    The inheritance tree has been splitted/simplificated.

    + Legend :
    +
    +      
    +        
    +        
    +      
    ClassA  ClassA is abstract
    ClassB  ClassB is instanciable
    +
    +
    + +

    Tracks

    + +
    TrackMarker +
    TrackElement +
    + +
    SegmentObserver +
    TrackSegment +
    TrackFixedSegment +
    + +
    Track +
    + +
    HorizontalTrack +
    VerticalTrack +
    + +
    RoutingPlane +
    + +

    Algorithm

    + +
    DataNegociate +
    RoutingEvent::Key +
    RoutingEvent +
    RoutingEventQueue +
    RoutingEventLoop +
    RoutingEventHistory +
    Session +
    NegociateWindow +
    + +
    + Transient Data Structures For RoutingEvent + +
    SegmentAction +
    Manipulator +
    SegmentFsm +
    + +

    Kite Engine

    + +
    Kite +
    KiteEngine +
    + +
    + +
    Customized Class Hierarchy + Return to top of page +
    + +
    Kite Documentation + Copyright © 2008-2013 UPMC. All rights reserved +
    + + diff --git a/kite/doc/customSummary.html b/kite/doc/customSummary.html new file mode 100644 index 00000000..f1f46a24 --- /dev/null +++ b/kite/doc/customSummary.html @@ -0,0 +1,86 @@ + + + + + + Kite Documentation + + +

    Kite Documentation

    +
    + + + + + + + + + +
    SummaryNamespacesClass HierarchyClassesMember Index
    +
    +
    +
    + + + +

    Kite Documentation Summary

    +
    +

    The classical Doxygen module documentation could be accessed here.

    + + + +

    API documentations

    + +
    + +

    Developer's Notes

    + +
    + +
    + + + + + +
    Customized Concepts (a.k.a. modules)Return to top of page
    + + + + + +
    Kite DocumentationCopyright © 2005-2013 LIP6. All rights reserved
    + + diff --git a/kite/doc/notes.dox b/kite/doc/notes.dox new file mode 100644 index 00000000..8664e043 --- /dev/null +++ b/kite/doc/notes.dox @@ -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 + * + * - Determinism checking. 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 + * + * - Lazy Update. 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 + * + * LUT lookup change: When breaking a TrackSegment, the break may + * not occurs in the associated canonical AutoSegment. In that case the + * dogleg[O] will not match the one that is looked up + * for the broken (canonical) segment. Thus it was not a bug but a + * misunderstanding... + * + * Overlap of perpandiculars after a dogleg creation: + * 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: 1 lambda == 1 micron. + * + * - Run the commands in NanoRoute: + * - loadLefFile design.lef + * - loadDefFile design.def + * - generateTracks + * - generateVias + * - setNanoRouteMode -quiet -drouteFixAntenna 0 + * - setNanoRouteMode -quiet -drouteStartIteration default + * - setNanoRouteMode -quiet -routeTopRoutingLayer default + * - setNanoRouteMode -quiet -routeBottomRoutingLayer 2 + * - setNanoRouteMode -quiet -drouteEndIteration default + * - setNanoRouteMode -quiet -routeWithTimingDriven false + * - setNanoRouteMode -quiet -routeWithSiDriven false + * - routeDesign -globalDetail + * + * - 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 (-routeBottomRoutingLayer 2). Those commands + * are issued through the graphical interface of NanoRoute. + * + * To see the resulting layout, do not forget to switch the view mode. + */ + + }