Forgotten doc files.
This commit is contained in:
parent
9965b34e9b
commit
f2192ae3bd
|
@ -0,0 +1,36 @@
|
||||||
|
// -*- mode: C++; explicit-buffer-name: "Constants.h<kite/doc>" -*-
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
//! \enum FunctionFlag
|
||||||
|
//! A set of flags to that can be passed to functions/methods througout
|
||||||
|
//! all Kite.
|
||||||
|
|
||||||
|
//! \var KtLoadGlobalRouting
|
||||||
|
//! Reload the global routing from a preciously saved run (\c .kgr file).
|
||||||
|
|
||||||
|
//! \var KtBuildGlobalRouting
|
||||||
|
//! Run the global router Knik.
|
||||||
|
|
||||||
|
//! \var KtAllowDoglegReuse
|
||||||
|
//! Allow sharing of dogleg.
|
||||||
|
|
||||||
|
//! \var KtDataSelf
|
||||||
|
//! \red{To be documented.}
|
||||||
|
|
||||||
|
//! \var KtNearest
|
||||||
|
//! Round the position to the nearest track axis.
|
||||||
|
|
||||||
|
//! \var KtForce
|
||||||
|
//! Force to perform an action ignoring the "up to date" state.
|
||||||
|
|
||||||
|
//! \var KtResetCount
|
||||||
|
//! Tells to reset a counter.
|
||||||
|
|
||||||
|
//! \var KtWithPerpands
|
||||||
|
//! Ripup perpandiculars alongside the current segment.
|
||||||
|
|
||||||
|
//! \var KtWithConstraints
|
||||||
|
//! Force constraints recomputation.
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,217 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
/*! \class DataNegociate
|
||||||
|
* \brief Algorimthmic datas associated the TrackSegment
|
||||||
|
*
|
||||||
|
* The DataNegociate object contains all the informations the negociation
|
||||||
|
* algorithm needs to know about a TrackSegment. Those informations
|
||||||
|
* mostly describe the slackening and ripup state of that segment.
|
||||||
|
*
|
||||||
|
* <b>State related datas:</b>
|
||||||
|
* - The ripup count in the current state. The count is reset
|
||||||
|
* to zero at each state transition.
|
||||||
|
* - The slackening state (see DataNegociate::SlackState). The state
|
||||||
|
* indicate the \b next topological modification to be applied on
|
||||||
|
* the segment should the ripup count reach it's maximal value.
|
||||||
|
* - The associated RoutingEvent. If no RoutingEvent is present, it
|
||||||
|
* means the segment has been either successufully placed or the
|
||||||
|
* algorithm has given up trying to. If present, it is a \e pending
|
||||||
|
* request for placement.
|
||||||
|
*
|
||||||
|
* <b>Topological related datas:</b>
|
||||||
|
* - \c leftMinExtend, the potential minimal position of the segment
|
||||||
|
* left extension. May not be reachable due to other topological
|
||||||
|
* constraints.
|
||||||
|
* - \c rightMinExtend, the potential minimal position of the segment
|
||||||
|
* right extension.
|
||||||
|
* - \c terminals, the number of terminals attached to this segment.
|
||||||
|
* - \c attractors, a table of coordinates of the end points of the
|
||||||
|
* perpandiculars to this segment. Used to compute the wiring delta
|
||||||
|
* if we move the axis of the segment.
|
||||||
|
* - \c perpandiculars, a \c vector of the perpandicular TrackElement.
|
||||||
|
* This is a fast-access cache. It must be updated each time the
|
||||||
|
* topology of the net is modificated.
|
||||||
|
* - \c perpandicularFree, the free interval defined by the perpandiculars,
|
||||||
|
* that is for the sgement axis.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secAttractorsComputation Perpandiculars, Free, Attractors & Wiring Delta
|
||||||
|
*
|
||||||
|
* All those informations are computed and updated by the
|
||||||
|
* DataNegociate::update() method, which relies on:
|
||||||
|
* - AutoSegment::getTopologicalInfos()
|
||||||
|
* - AutoSegment::getTerminalCount()
|
||||||
|
*
|
||||||
|
* \red{They must be reviewed as they do not take advantage of the new}
|
||||||
|
* \red{AutoSegment structuration.}
|
||||||
|
*
|
||||||
|
* For every perpandicular set of AutoSegment to the TrackSegment
|
||||||
|
* we want to place, get the coordinates of the extremity not connected
|
||||||
|
* to the segment and put that coordinate into a table associated with
|
||||||
|
* it's \e spin. The \e spin tells if the extremity is attracting the
|
||||||
|
* segment \e up or \e down (for an horizontal segment). The \e spin
|
||||||
|
* is incremented for up and decremented for down. After all the
|
||||||
|
* extremities have been processeds, we took into account only the
|
||||||
|
* coordinates with a non-zero spin, which means they truly attract
|
||||||
|
* the segment (whatever the direction).
|
||||||
|
*
|
||||||
|
* \image html DataNegociate-1.png "Fig 1: Attractors Computation"
|
||||||
|
*
|
||||||
|
* The <em>wiring delta</em> is the total wire length needed to connect
|
||||||
|
* from the attractors to the segment, should it be placed on \c axis.
|
||||||
|
*
|
||||||
|
* \image html DataNegociate-2.png "Fig 2: Wiring Delta"
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secDataNegociateModifications Modifications History
|
||||||
|
*
|
||||||
|
* Main changes in DataNegociate class design:
|
||||||
|
* - Merge in the separate class \c Cost.
|
||||||
|
* - Suppress the \c SlackState::Desalignate, due to the simplificated
|
||||||
|
* structure of the AutoSegment/AutoContacts (no more collapseds, or
|
||||||
|
* forced alignements).
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \enum DataNegociate::SlackState
|
||||||
|
//! Describe the various stages of a TrackSegment slackening.
|
||||||
|
//! The numerical values are choosen so we can increment them
|
||||||
|
//! as a counter.
|
||||||
|
|
||||||
|
//! \var DataNegociate::RipupPerpandiculars
|
||||||
|
//! Force perpandiculars to be riped up as well as the TrackSegment,
|
||||||
|
//! then schedule the placement of the TrackSegment \e before it's perpandiculars.
|
||||||
|
|
||||||
|
// \var DataNegociate::Desalignate
|
||||||
|
//! If the TrackSegment is made of multiple TrackSegments with a forced
|
||||||
|
//! alignement, suppress the alignement constraint.
|
||||||
|
//!
|
||||||
|
//! \red{This should be deprecated now}.
|
||||||
|
|
||||||
|
//! \var DataNegociate::Minimize
|
||||||
|
//! Try to displace the perpandiculars so the TrackSegment is
|
||||||
|
//! reduced to it's minimal length.
|
||||||
|
|
||||||
|
//! \var DataNegociate::Dogleg
|
||||||
|
//! Break the segment into two smaller ones.
|
||||||
|
|
||||||
|
//! \var DataNegociate::Slacken
|
||||||
|
//! Create additional wiring so threre is no more contraints transmitted
|
||||||
|
//! by the perpandiculars or the terminal contacts.
|
||||||
|
|
||||||
|
//! \var DataNegociate::ConflictSolveByHistory
|
||||||
|
//! Try to solve a conflict between a set of global segments by
|
||||||
|
//! analysing the event/ripup history. See SegmentFsm::conflictSolveByHistory().
|
||||||
|
|
||||||
|
//! \var DataNegociate::ConflictSolveByPlaceds
|
||||||
|
//! Try to solve a conflict between a set of global segments by
|
||||||
|
//! analysing the current track context. See SegmentFsm::conflictSolveByPlaceds().
|
||||||
|
|
||||||
|
//! \var DataNegociate::LocalVsGlobal
|
||||||
|
//! \red{To be reviewed}.
|
||||||
|
|
||||||
|
//! \var DataNegociate::MoveUp
|
||||||
|
//! The segment is to be moved up (if possible).
|
||||||
|
|
||||||
|
//! \var DataNegociate::MaximumSlack
|
||||||
|
//! The final state, topological modifications are exhausteds, if it
|
||||||
|
//! cannot place at this point, it never will.
|
||||||
|
|
||||||
|
//! \var DataNegociate::Unimplemented
|
||||||
|
//! Used only during the development stage, telling that the state is
|
||||||
|
//! not available yet.
|
||||||
|
|
||||||
|
//! \var DataNegociate::Repair
|
||||||
|
//! The router is in repair mode.
|
||||||
|
|
||||||
|
//! \function bool DataNegociate::hasRoutingEvent () const;
|
||||||
|
//! \sreturn \true if there is a pending RoutingEvent for this TrackSegment.
|
||||||
|
|
||||||
|
//! \function RoutingEvent* DataNegociate::getRoutingEvent () const;
|
||||||
|
//! \sreturn The pending RoutingEvent. \c NULL will be returned if there is no
|
||||||
|
//! pending event, meaning that the segment has been placed.
|
||||||
|
|
||||||
|
//! \function TrackSegment* DataNegociate::getTrackSegment () const;
|
||||||
|
//! \sreturn The associated TrackSegment.
|
||||||
|
|
||||||
|
//! \function Track* DataNegociate::getTrack () const;
|
||||||
|
//! \sreturn A proxy accessor for the segment's track.
|
||||||
|
|
||||||
|
//! \function DbU::Unit DataNegociate::getLeftMinExtend () const;
|
||||||
|
//! \sreturn The minimum extend possible of the segment's source (left) ending.
|
||||||
|
//! Computed by DataNegociate::update().
|
||||||
|
|
||||||
|
//! \function DbU::Unit DataNegociate::getRightMinExtend () const;
|
||||||
|
//! \sreturn The minimum extend possible of the segment's target (right) ending.
|
||||||
|
//! Computed by DataNegociate::update().
|
||||||
|
|
||||||
|
//! \function unsigned int DataNegociate::getTerminals () const;
|
||||||
|
//! \sreturn The number of terminal to which this segment is connected
|
||||||
|
//! Computed by DataNegociate::update().
|
||||||
|
//!
|
||||||
|
//! \red{Must be refined: direct or indirect?}.
|
||||||
|
|
||||||
|
//! \function Net* DataNegociate::getNet () const;
|
||||||
|
//! \sreturn A cached accessor to the segment's net (for faster access).
|
||||||
|
|
||||||
|
//! \function unsigned int DataNegociate::getState () const;
|
||||||
|
//! \sreturn The current state (see DataNegociate::SlackState).
|
||||||
|
|
||||||
|
//! \function unsigned int DataNegociate::getStateCount () const;
|
||||||
|
//! \sreturn The number of times we have reached the ripup limit while in
|
||||||
|
//! this stage.
|
||||||
|
|
||||||
|
//! \function unsigned int DataNegociate::getRipupCount () const;
|
||||||
|
//! \sreturn The number of times the segment has been riped up in this stage.
|
||||||
|
|
||||||
|
//! \function unsigned int DataNegociate::getStateAndRipupCount () const;
|
||||||
|
//! \return A composite number combining the state and the ripup count:
|
||||||
|
//! <code>(state<<4)+ripup</code>.
|
||||||
|
|
||||||
|
//! \function DbU::Unit DataNegociate::getWiringDelta ( DbU::Unit axis ) const;
|
||||||
|
//! \sreturn The wiring length needed to connect to the attractors if the segment
|
||||||
|
//! is put on \c axis. The lower, the better...
|
||||||
|
|
||||||
|
//! \function const Interval& DataNegociate::getPerpandicularFree () const;
|
||||||
|
//! \sreturn The range of legal positions generated only by the perpandiculars.
|
||||||
|
|
||||||
|
//! \function void DataNegociate::setState ( unsigned int state, unsigned int flags=0 );
|
||||||
|
//! Set or reset the slacking state (see SlackState). If the \c state is the
|
||||||
|
//! same as the current one, the state count is incremented. If the new state
|
||||||
|
//! changes or \c flags contain KtReset, the state count is reset to one.
|
||||||
|
|
||||||
|
//! \function void DataNegociate::setRoutingEvent ( RoutingEvent* event );
|
||||||
|
//! Associate \c event to this TrackSegment.
|
||||||
|
|
||||||
|
//! \function void DataNegociate::setRipupCount ( unsigned int count );
|
||||||
|
//! Directly sets the ripup count to \c count.
|
||||||
|
|
||||||
|
//! \function void DataNegociate::incRipupCount ();
|
||||||
|
//! Increment the ripup count. No check is performed for bound limit.
|
||||||
|
|
||||||
|
//! \function void DataNegociate::decRipupCount ();
|
||||||
|
//! Decrement the ripup count (will never go below zero).
|
||||||
|
|
||||||
|
//! \function void DataNegociate::resetRipupCount ();
|
||||||
|
//! Reset the ripup count to zero.
|
||||||
|
|
||||||
|
//! \function void DataNegociate::resetStateCount ();
|
||||||
|
//! Reset the state count to zero.
|
||||||
|
|
||||||
|
// \function void DataNegociate::invalidate ( unsigned int flags=0 );
|
||||||
|
// Invalidate the associated RoutingEvent.
|
||||||
|
//
|
||||||
|
// Possible values for \c flags :
|
||||||
|
// - Kite::KtWithPerpands
|
||||||
|
// - Kite::KtWithConstraints
|
||||||
|
|
||||||
|
//! \function void DataNegociate::update ();
|
||||||
|
//! Recompute \c leftMinExtend, \c righMinExtend, number of terminals and
|
||||||
|
//! attractors positions.
|
||||||
|
//!
|
||||||
|
//! \remark The constructor do not calls it. It is to the algorithm responsability
|
||||||
|
//! to call it before using the computed datas.
|
||||||
|
|
||||||
|
}
|
|
@ -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()).
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
/*! \class KiteEngine
|
||||||
|
*
|
||||||
|
* \brief The Kite Tool
|
||||||
|
*
|
||||||
|
* <b>Lookup Mechanism</b>
|
||||||
|
*
|
||||||
|
* Please look at Kite::Session for an explanation of the lookup
|
||||||
|
* mechanism from Hurricane::Segment or Katabatic::AutoSegment to
|
||||||
|
* TrackSegment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//! \function const Name& KiteEngine::staticGetName ();
|
||||||
|
//! \sreturn The unique string identifier for the KiteEngine class of ToolEngine.
|
||||||
|
|
||||||
|
//! \function KiteEngine* KiteEngine::create ( Cell* cell );
|
||||||
|
//! Create a KiteEngine on \c cell.
|
||||||
|
|
||||||
|
//! \function KiteEngine* KiteEngine::get ( const Cell* cell );
|
||||||
|
//! \sreturn The KiteEngine associated to \c cell. \c NULL if there isn't.
|
||||||
|
|
||||||
|
//! \function KatabaticEngine* KiteEngine::base ();
|
||||||
|
//! \sreturn The KiteEngine, casted as it's base class (KatabaticEngine).
|
||||||
|
|
||||||
|
//! \function Configuration* KiteEngine::getKiteConfiguration ();
|
||||||
|
//! \sreturn The KiteEngine configuration. The Kite Configuration is a derived
|
||||||
|
//! class of KatabaticConfiguration.
|
||||||
|
|
||||||
|
//! \function Configuration* KiteEngine::getConfiguration ();
|
||||||
|
//! \sreturn The KiteEngine configuration.
|
||||||
|
|
||||||
|
//! \function Net* KiteEngine::getBlockageNet ();
|
||||||
|
//! \sreturn The Net which is used to mark the blockage segments. It's not part of
|
||||||
|
//! the Configuration <em>per se</em> but an isolated attribute.
|
||||||
|
|
||||||
|
//! \function bool KiteEngine::getToolSuccess () const;
|
||||||
|
//! \sreturn \true if the tool was successful, that is, all the Net were routeds.
|
||||||
|
|
||||||
|
//! \function unsigned long KiteEngine::getEventsLimit () const;
|
||||||
|
//! \sreturn The maximal number of allowed routing events. This limit is a security
|
||||||
|
//! against infinite looping, be sure that it is great enough not to
|
||||||
|
//! prevent normal routing completion.
|
||||||
|
|
||||||
|
//! \function unsigned long KiteEngine::getRipupLimit ( unsigned int type ) const;
|
||||||
|
//! \sreturn the maximum ripup allowed of a segment of \c type.
|
||||||
|
|
||||||
|
//! \function unsigned long KiteEngine::getRipupCost () const;
|
||||||
|
//! \sreturn the differential used while comparing two ripup costs.
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,266 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
/*! \class Manipulator
|
||||||
|
* \brief Handle TrackElement ripup & topological modifications.
|
||||||
|
*
|
||||||
|
* \section secManipStruct Manipulator Structure
|
||||||
|
*
|
||||||
|
* A Manipulator basically binds together a TrackElement, it's
|
||||||
|
* DataNegociate and RoutingEvent (cached for fast access), and
|
||||||
|
* \b a SegmentFsm.
|
||||||
|
*
|
||||||
|
* <em>The TrackElement may differs from the one of the SegmentFsm.</em>
|
||||||
|
* This can occurs when manipulating perpandiculars or segments from
|
||||||
|
* other nets in conflict. For example: Manipulator::isCaged().
|
||||||
|
*
|
||||||
|
* In the following documentation, the segment <em>which is associated
|
||||||
|
* to the SegmentFsm</em> will be called the <em>reference segment</em>.
|
||||||
|
*
|
||||||
|
* \section secManipDelayed Delayed Modifications
|
||||||
|
*
|
||||||
|
* It is important to note that when a Manipulator is called to
|
||||||
|
* modificate a TrackElement, nothing is actually done by the
|
||||||
|
* Manipulator itself. Instead, the Manipulator create the
|
||||||
|
* relevant SegmentAction (s) that are stored in the SegmentFsm.
|
||||||
|
* The action themselves are done at the end of the SegmentFsm
|
||||||
|
* lifecycle (wrapped inside a Session).
|
||||||
|
*
|
||||||
|
* \red{This is not true!} When dogleg are created, the topology is
|
||||||
|
* immediatly modificated. That way of doing must be clarified.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \enum Manipulator::FunctionFlag
|
||||||
|
//! The various flags that can be passed to the Manipulator methods.
|
||||||
|
|
||||||
|
//! \var Manipulator::ToRipupLimit
|
||||||
|
//! The ripup limit must be immediatly to it's limit for the current
|
||||||
|
//! state.
|
||||||
|
|
||||||
|
//! \var Manipulator::AllowExpand
|
||||||
|
//! Allow break points for dogleg not to be exactly on the requested
|
||||||
|
//! position. Meaning that they are moved to the least congested
|
||||||
|
//! GCell.
|
||||||
|
|
||||||
|
//! \var Manipulator::NoExpand
|
||||||
|
//! Breakpoints for dogleg are kept right where they are requested.
|
||||||
|
|
||||||
|
//! \var Manipulator::PerpandicularsFirst
|
||||||
|
//! Reorder the events so that perpandiculars segments are re-processed
|
||||||
|
//! before their reference segment. By default this is the other way
|
||||||
|
//! around.
|
||||||
|
|
||||||
|
//! \var Manipulator::ToMoveUp
|
||||||
|
//! Try to move up ripped up segments.
|
||||||
|
|
||||||
|
//! \var Manipulator::AllowLocalMoveUp
|
||||||
|
//! Allow local segments to be moved up (forbidden by default).
|
||||||
|
|
||||||
|
//! \var Manipulator::AllowTerminalMoveUp
|
||||||
|
//! Allow terminal segments to be moved up (forbidden by default).
|
||||||
|
|
||||||
|
//! \var Manipulator::AllowShortPivotUp
|
||||||
|
//! Allow short segment yo be pivoted up.
|
||||||
|
|
||||||
|
//! \var Manipulator::NoDoglegReuse
|
||||||
|
//! When creating a dogleg, the default behavior is \e not to create a
|
||||||
|
//! new one if there's already one in the same GCell. If this flag is
|
||||||
|
//! set, a second dogleg will be created.
|
||||||
|
|
||||||
|
//! \var Manipulator::RightAxisHint
|
||||||
|
//! An explicit right axis hint has been supplied as argument.
|
||||||
|
|
||||||
|
//! \var Manipulator::LeftAxisHint
|
||||||
|
//! An explicit left axis hint has been supplied as argument.
|
||||||
|
|
||||||
|
//! \var Manipulator::NotOnLastRipup
|
||||||
|
//! The reference segment has still more than one ripup to go for
|
||||||
|
//! the given state.
|
||||||
|
|
||||||
|
//! \function Manipulator::Manipulator ( TrackElement* segment, SegmentFsm& fsm );
|
||||||
|
//! \param segment The TrackElement to manipulate.
|
||||||
|
//! \param fsm The associated SegmentFsm.
|
||||||
|
//!
|
||||||
|
//! Construct a new Manipulator on \c segment.
|
||||||
|
|
||||||
|
//! \function TrackElement* Manipulator::getSegment () const;
|
||||||
|
//! \sreturn The working TrackElement.
|
||||||
|
|
||||||
|
//! \function DataNegociate* Manipulator::getData () const;
|
||||||
|
//! \sreturn The DataNegociate of the TrackElement (act as a cache).
|
||||||
|
|
||||||
|
//! \function RoutingEvent* Manipulator::getEvent () const;
|
||||||
|
//! \sreturn The RoutingEvent associated to the TrackElement (act as a cache).
|
||||||
|
|
||||||
|
//! \function bool Manipulator::canRipup ( unsigned int flags ) const;
|
||||||
|
//! \sreturn \true if the maximum ripup, for the given SegmentFsm::State has not
|
||||||
|
//! been reached. If \c flags contains Manipulator::HasNextRipup, return
|
||||||
|
//! \true \b only if it still have at least one ripup to go.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::isCaged ( DbU::Unit axis ) const;
|
||||||
|
//! \sreturn \true if the segment is enclosed (in it's Track) by two fixed or
|
||||||
|
//! blockage segments which at least one is closer than 10 lambdas from
|
||||||
|
//! \c axis. Mostly used to know if a perpandicular is actually restricting
|
||||||
|
//! the axis span of a reference segment.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::ripup ( unsigned int type, DbU::Unit axisHint=0 );
|
||||||
|
//! \param type The type of ripup action.
|
||||||
|
//! \param axisHint An indication as where to move the riped up segment.
|
||||||
|
//! \return \true if the operation has succedeed.
|
||||||
|
//!
|
||||||
|
//! If the TrackElement can be ripped up, schedule a ripup action, possibly
|
||||||
|
//! with a hint for the preferred axis position.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::ripupPerpandiculars ( unsigned int flags );
|
||||||
|
//! Schedule a ripup of all the perpandiculars of the reference segment.
|
||||||
|
//! \c flags that modificate the behavior:
|
||||||
|
//! - Manipulator::PerpandicularsFirst : the queue will be reordered so
|
||||||
|
//! that all the perpandiculars are re-processed (placed) before the
|
||||||
|
//! reference segment.
|
||||||
|
//! - Manipulator::ToRipupLimit : the ripup count of the reference segment
|
||||||
|
//! is set to the limit (i.e. only one more attempt before a slackening
|
||||||
|
//! occurs).
|
||||||
|
//!
|
||||||
|
//! The method will fails (return \false) if at least one perpandicular can't
|
||||||
|
//! be changed of track (i.e. ripped up) \b and none of it's neighbors could
|
||||||
|
//! be ripped up either. Meaning that the free span on that track cannot be
|
||||||
|
//! changed.
|
||||||
|
|
||||||
|
//! \function void Manipulator::repackPerpandiculars ();
|
||||||
|
//! Ripup all the perpandiculars of the reference segment, except fixed or
|
||||||
|
//! globals. The reference segment is rescheduled first (before it's
|
||||||
|
//! perpandicular).
|
||||||
|
//!
|
||||||
|
//! This function may be used to find a better placement, maximizing the
|
||||||
|
//! overlap of the various perpandiculars.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::ripple ();
|
||||||
|
//! \sreturn true if the reference segment is local.
|
||||||
|
//!
|
||||||
|
//! Applies only on reference segments that are of local type.
|
||||||
|
//! Tries to make room for the reference segment by ripping up it's neigbors
|
||||||
|
//! on the parallels tracks. On a vertical plane, left neigbors are shifted
|
||||||
|
//! one track left (trough axis hint) and right ones, one track right.
|
||||||
|
//! Note that they are ripped up and the shift is just a hint, there's no
|
||||||
|
//! guarantee that the router can honor it.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::minimize ();
|
||||||
|
//! \sreturn true if the reference segment can be mimized in a suitable track hole.
|
||||||
|
//!
|
||||||
|
//! Compute the miminal span of the reference segment, summing up contraints
|
||||||
|
//! from source anchor and target anchors (if any) and perpandiculars.
|
||||||
|
//! Then find holes in the avalaible tracks, and check if one is suitable
|
||||||
|
//! for the miminized segment (try first the biggest hole).
|
||||||
|
//!
|
||||||
|
//! This operation can only be called once on a segment (a flag is set in the
|
||||||
|
//! event).
|
||||||
|
|
||||||
|
//! \function bool Manipulator::slacken ( unsigned int flags=KbNoFlags );
|
||||||
|
//! Simple proxy towards TrackElement::slacken().
|
||||||
|
//!
|
||||||
|
//! \red{To be reviewed.}
|
||||||
|
|
||||||
|
//! \function bool Manipulator::pivotUp ();
|
||||||
|
//! Tries to move up the reference segment. The segment will be moved
|
||||||
|
//! up only if a half track is free (for a local) or a full track is
|
||||||
|
//! free (for a global).
|
||||||
|
//!
|
||||||
|
//! This function do not modifies/create perpandiculars.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::pivotDown ();
|
||||||
|
//! Tries to move down the reference segment. The segment will be moved
|
||||||
|
//! up only if \e two track are free (whether global or local). Is is more
|
||||||
|
//! restrictive than Manipulator::pivotUp().
|
||||||
|
//!
|
||||||
|
//! This function do not modifies/create perpandiculars.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::moveUp ( unsigned int flags );
|
||||||
|
//! Tries to move up a segment, if there is enough space in the RoutingPlane
|
||||||
|
//! above and in the same direction.
|
||||||
|
//!
|
||||||
|
//! This function may modificate perpandiculars in order to maintain
|
||||||
|
//! connexity.
|
||||||
|
//!
|
||||||
|
//! \red{To be reviewed.}
|
||||||
|
|
||||||
|
//! \function bool Manipulator::makeDogleg ();
|
||||||
|
//! \sreturn \false if the segment is \e not local or the dogleg cannot be done.
|
||||||
|
//!
|
||||||
|
//! For \e local reference segment only, look in the first track candidate
|
||||||
|
//! for other segment overlapping and break the reference accordingly.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::makeDogleg ( Interval overlap );
|
||||||
|
//! Create a dogleg to avoid the obstructed interval \c overlap.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::makeDogleg ( DbU::Unit position );
|
||||||
|
//! Create a dogleg in the GCell under \c position.
|
||||||
|
|
||||||
|
//! \function bool Manipulator::relax ( Interval overlap, unsigned int flags=AllowExpand );
|
||||||
|
//! Break the reference segment so it can detour around the interval
|
||||||
|
//! \c overlap. If \c overlap is completly enclosed inside the span of
|
||||||
|
//! the reference segment two dogleg will be created. If the overlap occurs
|
||||||
|
//! only on one side of the reference segment, only one dogleg will be
|
||||||
|
//! created.
|
||||||
|
//!
|
||||||
|
//! If \c flags contains Manipulator::AllowExpand, the dogleg are not created
|
||||||
|
//! exactly at the edges of the overlap but on the lowest density GCell
|
||||||
|
//! (outside the overlap interval).
|
||||||
|
//!
|
||||||
|
//! The axis of the created dogleg are sets so that the broken part of the
|
||||||
|
//! segment completly enclose \c overlap. That is, the orignal segment no
|
||||||
|
//! longer intersect with \c overlap. So the min dogleg is pushed to the
|
||||||
|
//! left and the max to the right if they are in the same GCell as the
|
||||||
|
//! min/max of \c overlap. Otherwise (they have been expanded), they are
|
||||||
|
//! put in the center of the GCell.
|
||||||
|
//!
|
||||||
|
//! We do not allow to dogleg twice in the same GCell, so if min or max
|
||||||
|
//! is in respectively the first or last GCell, it is not done. Moreover
|
||||||
|
//! if there is only one dogleg \e and it is in the first or last GCell,
|
||||||
|
//! the relax method is cancelled (and returns \false). It means that
|
||||||
|
//! this is the segment which is likely to be enclosed inside \c overlap.
|
||||||
|
//!
|
||||||
|
//! \redB{Important:} The doglegs are created immediatly and not in a delayed
|
||||||
|
//! fashion like the SegmentAction.
|
||||||
|
//!
|
||||||
|
//! \image html ManipulatorRelax-1.png "Two Doglegs (min & max), no expansion"
|
||||||
|
//! \image html ManipulatorRelax-2.png "Two Doglegs (min & max), with expansion"
|
||||||
|
//! \image html ManipulatorRelax-3.png "One Dogleg (min)"
|
||||||
|
//! \image html ManipulatorRelax-4.png "One Dogleg (max)"
|
||||||
|
|
||||||
|
//! \function bool Manipulator::insertInTrack ( size_t i );
|
||||||
|
//! Try to insert the reference segment in the track at index \c i (in the cost
|
||||||
|
//! table from SegmentFsm). The insertion is done by ripping up overlapping
|
||||||
|
//! segment or shrinking them to left/right if possible.
|
||||||
|
//!
|
||||||
|
//! \red{This operation ripup the processed segment neighbors (and their perpandiculars).}
|
||||||
|
|
||||||
|
//! \function bool Manipulator::forceToTrack ( size_t i );
|
||||||
|
//! Try to insert the reference segment in the track at index \c i (in the cost
|
||||||
|
//! table from SegmentFsm). The insertion is done by \e forcibly ripping up the
|
||||||
|
//! overlapping segments \b and their perpandiculars.
|
||||||
|
//!
|
||||||
|
//! \red{This operation ripup the processed segment neighbors (and their perpandiculars).}
|
||||||
|
|
||||||
|
//! \function bool Manipulator::shrinkToTrack ( size_t i, unsigned int flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint );
|
||||||
|
//! Attempt to minimize the reference segment to fit into the track.
|
||||||
|
//! For this operation to succeed, the minimal span of the segment must
|
||||||
|
//! not overlap any other segment already in the track. To reach the
|
||||||
|
//! minimal span the perpandiculars are ripped up with an axis hint
|
||||||
|
//! which is the center of the minimal span or the explicit value given
|
||||||
|
//! as arguments \c leftAxisHint and \c rightAxisHint if \c flags contains
|
||||||
|
//! respectively Manipulator::LeftAxisHint or Manipulator::RightAxisHint.
|
||||||
|
//!
|
||||||
|
//! \red{This operation ripup the processed segment itself and its perpandiculars.}
|
||||||
|
|
||||||
|
//! \function bool Manipulator::forceOverLocals ();
|
||||||
|
//! Loop over all the candidate tracks and, insert in the first which
|
||||||
|
//! all conflicting segments are locals (rip them up).
|
||||||
|
|
||||||
|
//! \function bool Manipulator::repackPerpandiculars ();
|
||||||
|
//! Ripup all perpandiculars and the reference segment itself for a complete
|
||||||
|
//! re-placement. The reference segment will be reprocessed \e before it's
|
||||||
|
//! perpandiculars.
|
||||||
|
|
||||||
|
}
|
|
@ -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.
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,597 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
/*! \class RoutingEvent
|
||||||
|
* \brief Manage TrackSegment routing requests.
|
||||||
|
*
|
||||||
|
* The \RoutingEvent is the workhorse of Kite. A \RoutingEvent is
|
||||||
|
* associated to one \TrackSegment. One \TrackSegment could be
|
||||||
|
* associated to many \RoutingEvent in the queue, but only one
|
||||||
|
* of those is active (marked as unprocessed).
|
||||||
|
*
|
||||||
|
* \see ClassManipulator.
|
||||||
|
*
|
||||||
|
* \section secProcessAlgorithm Description of the process() method
|
||||||
|
*
|
||||||
|
\code
|
||||||
|
void RoutingEvent::process ()
|
||||||
|
{
|
||||||
|
if ( isProcessed() ) return;
|
||||||
|
setProcessed ();
|
||||||
|
incRipupCount ();
|
||||||
|
|
||||||
|
if ( getRipupCount() > MAX_RIPUP_COUNT ) {
|
||||||
|
// We are *not* in ripup mode.
|
||||||
|
// The event's segment has to be topologically modified.
|
||||||
|
modifyTopology ( _segment );
|
||||||
|
} else {
|
||||||
|
// We are in ripup mode.
|
||||||
|
// Other overlaping segments are to be removeds/pusheds. It can result in
|
||||||
|
// segment breaking *if* other segment came from an already routed GCell.
|
||||||
|
|
||||||
|
// optimal, constraint, perpandicular.
|
||||||
|
computeAllIntervals ();
|
||||||
|
|
||||||
|
// Find & order all candidates Tracks.
|
||||||
|
candidates = computeCostOnCandidateTracks ();
|
||||||
|
sort ( candidates );
|
||||||
|
|
||||||
|
if ( candidates[0].isFree() ) {
|
||||||
|
// Case -A.1- "Free Track".
|
||||||
|
candidate[0].insert ( _segment );
|
||||||
|
} else if ( candidates[0].isSoftOverlap()
|
||||||
|
|| candidates[0].isHardOverlap() ) {
|
||||||
|
// Case -A.2- "Soft Overlap".
|
||||||
|
// Case -A.3- "Hard Overlap".
|
||||||
|
for ( size_t i=0 ; i<candidates.size() ; i++ ) {
|
||||||
|
if ( candidates[0].insertInTrack ( _segment ) ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Case -B- "Infinite Cost".
|
||||||
|
// Attention: meaning's changed, *infinite* only in case of
|
||||||
|
// conflict with a *fixed* other segment.
|
||||||
|
modifyTopology ( _segment );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore Track coherency before processing any other event.
|
||||||
|
Session::revalidate ();
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
* \section secRoutingIntervalToDo ToDo
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>New \c isLocal() method on \TrackSegment. Tells if the \TrackSegment
|
||||||
|
* is associated only to local AutoSegment.
|
||||||
|
* <li>Increase the overlap cost of a \TrackSegment from an already routed
|
||||||
|
* GCell routing set.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secRoutingEventInterval The various intervals of a RoutingEvent
|
||||||
|
*
|
||||||
|
* The three Intervals controlling a RoutingEvent : all those intervals
|
||||||
|
* defines the track range in which the \TrackSegment could be inserted.
|
||||||
|
* <ul>
|
||||||
|
* <li>The <i>optimal</i> interval : where the \Net wirelength will be
|
||||||
|
* minimal (comes from \c Katabatic::AutoSegment).
|
||||||
|
* <li>The <i>constraint</i> interval : the interval outside of which
|
||||||
|
* the \Net connexity would be broken. This is the bigger interval
|
||||||
|
* but it must be strictly respected (also comes from
|
||||||
|
* \c Katabatic::AutoSegment).
|
||||||
|
* <li>The <i>perpandicular</i> interval : for each perpandicular
|
||||||
|
* \TrackSegment connected, the intersection of the free interval
|
||||||
|
* around them in their track.
|
||||||
|
*
|
||||||
|
* It is important to note that the \TrackSegment overlaping in the
|
||||||
|
* target track is not removed from the track. It is it's perpandiculars
|
||||||
|
* which are, along with a modification of theirs left axis weight and/or
|
||||||
|
* right axis weight.
|
||||||
|
*
|
||||||
|
* Second remark: no overlap will be created (due to the non-removal of
|
||||||
|
* overlaping \TrackSegments) because the insertion is delayed in case
|
||||||
|
* of overlap.
|
||||||
|
* </ul>
|
||||||
|
* The perpandicular interval comes from perpandicular constraints on \TrackSegment
|
||||||
|
* of the <i>same</i> \c Net. The left/right axis weights comes from requests of
|
||||||
|
* <i>other</i> \c Nets.
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-1.png "RoutingEvent Intervals"
|
||||||
|
* \image latex RoutingEvent-1.pdf "RoutingEvent Intervals" width=0.6\textwidth
|
||||||
|
*
|
||||||
|
* Example of perpandicular interval computation :
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-2.png "Perpandicular Interval"
|
||||||
|
* \image latex RoutingEvent-2.pdf "Perpandicular Interval"
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secRoutingEventRules Rules governing RoutingEvents
|
||||||
|
*
|
||||||
|
* \RoutingEvent respect the following rules:
|
||||||
|
* <ul>
|
||||||
|
* <li>A \TrackSegment can only be displaced by it's associated \RoutingEvent.
|
||||||
|
* <li>Corollary: the only \TrackSegment displaced while processing a
|
||||||
|
* \RoutingEvent is the one associated to the event.
|
||||||
|
* <li>Conflicts occurs between the \RoutingEvent \TrackSegment and already
|
||||||
|
* placed others \TrackSegment.
|
||||||
|
*
|
||||||
|
* The conflict can be solved by displacing/modifying <i>others</i>
|
||||||
|
* \TrackSegment or by modifying the to be inserted one. In the later
|
||||||
|
* case, the newly created or modified \TrackSegment are (re)scheduleds
|
||||||
|
* <i>before</i> the would be inserted.
|
||||||
|
* <li>Conflicting \TrackSegments are only removed from their \Track
|
||||||
|
* but their axis remains unchanged. Movement requests are passed
|
||||||
|
* through increase of the left/right axis weights, if needed.
|
||||||
|
* <li>\TrackSegment are inserted only, and only if there is enough free space.
|
||||||
|
* That is, if any kind of overlap occurs, it is <i>not</i> inserted
|
||||||
|
* but <i>rescheduled</i>. The blocking \TrackSegments are then
|
||||||
|
* rescheduled <i>after</i> the current one.
|
||||||
|
* <li>Each \RoutingEvent processing takes place inside a one atomic
|
||||||
|
* Session. That is, the coherency of the data-base is restored
|
||||||
|
* immediatly afterward (both Kite & Katabatic).
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* \remark Be very careful to distinguish between Session commands, which affects
|
||||||
|
* \Track and \TrackSegment insertion/update/removal and schedule/re-schedule
|
||||||
|
* events, which relates to the negociation algorithm.
|
||||||
|
*
|
||||||
|
* Re-ordering rules:
|
||||||
|
* <ol>
|
||||||
|
* <li>In normal mode, that is, no maximum ripup has been reached, the
|
||||||
|
* blocking <i>other</i> \TrackSegment are removed and the current
|
||||||
|
* is rescheduled <i>before</i> them.
|
||||||
|
* <li>In maximum ripup mode, some \TrackSegment has to give way.
|
||||||
|
* <ul>
|
||||||
|
* <li>If the current one is modified, it must be rescheduled <i>after</i>
|
||||||
|
* it's modified bits are rescheduleds.
|
||||||
|
* <li>If <i>others</i> are modifieds they must be rescheduled <i>after</i>
|
||||||
|
* the current one (so it will grabs the place).
|
||||||
|
* </ul>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secRoutingEventCycle RoutingEvent life cycle
|
||||||
|
*
|
||||||
|
* As an active \RoutingEvent is associated with one and only one \TrackSegment
|
||||||
|
* we can talk indeferently of \RoutingEvent lifecycle or \TrackSegment
|
||||||
|
* lifecycle.
|
||||||
|
*
|
||||||
|
* Below is the ordered list of states that a \RoutingEvent could be in.
|
||||||
|
* The order correspond to increasing level of slackening/freedom.
|
||||||
|
* Transition between states occurs each time a maximum ripup is reached.
|
||||||
|
*
|
||||||
|
* <table>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center"> \b Id </td>
|
||||||
|
* <td align="center">\b Type</td>
|
||||||
|
* <td align="center"> \b Local </td>
|
||||||
|
* <td align="center"> \b Global </td>
|
||||||
|
* <td align="center">\b Action</td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">\e 1</td>
|
||||||
|
* <td align="center">\c Minimize</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td align="center">\e no</td>
|
||||||
|
* <td>try to fit into a hole</td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">\e 2</td>
|
||||||
|
* <td align="center">\c DogLeg</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td align="center">\e no</td>
|
||||||
|
* <td>Dogleg : analyse overlap and try to solve it by breaking (self)</td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">\e 3</td>
|
||||||
|
* <td align="center">\c Desalignate</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td>on a set of alignated \TrackSegment, suppress the
|
||||||
|
* alignment constraints, thus making then independants
|
||||||
|
* </td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">\e 4</td>
|
||||||
|
* <td align="center">\c Slacken</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td>if the target/source constraint is less than the
|
||||||
|
* GCell, adds perpandicular straps to free the \TrackSegment.
|
||||||
|
* This occurs to free from terminal constraints
|
||||||
|
* </td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">\e 5</td>
|
||||||
|
* <td align="center">\c ConflictSolve1</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td>try to find in the history a reccurent dislodger,
|
||||||
|
* and break (self) to accomodate it
|
||||||
|
* </td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">\e 6</td>
|
||||||
|
* <td align="center">\c ConflictSolve2</td>
|
||||||
|
* <td align="center">\e no</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td>try to find a Track on which we can dislodge
|
||||||
|
* an other \TrackSegment
|
||||||
|
* </td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">\e 7</td>
|
||||||
|
* <td align="center">\c MoveUp</td>
|
||||||
|
* <td align="center">\e no</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td>try to go on upper layer.
|
||||||
|
* </td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td align="center">\e 8</td>
|
||||||
|
* <td align="center">\c Unimplemented</td>
|
||||||
|
* <td align="center">\e no</td>
|
||||||
|
* <td align="center">\e yes</td>
|
||||||
|
* <td>we failed to place this \TrackSegment
|
||||||
|
* </td>
|
||||||
|
* </tr>
|
||||||
|
* </table>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secManageMaximumRipup Managing the maximum ripup case
|
||||||
|
*
|
||||||
|
\code
|
||||||
|
bool State::manageMaximumRipup ()
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if ( !_segment->isGlobal() ) {
|
||||||
|
// Candidates Tracks (ignore optimal & perpandiculars).
|
||||||
|
candidates = computeAllIntervals ();
|
||||||
|
overlap = _segment->getInterval();
|
||||||
|
|
||||||
|
for ( size_t i=0 ; i<candidates.size() ; i++ ) {
|
||||||
|
others = otherSegmentsConflicts(candidates[i]);
|
||||||
|
|
||||||
|
// Select Track with only one conflicting other.
|
||||||
|
if ( others.size() == 1 ) {
|
||||||
|
// Local vs. Local => reject.
|
||||||
|
// Local vs. Terminal => reject.
|
||||||
|
if ( others[0]->isLocal() || others[0]->isTerminal() ) continue;
|
||||||
|
|
||||||
|
// Local vs. Global (not routed yet).
|
||||||
|
if ( others[i]->getOrder() >= _segment->getOrder() ) {
|
||||||
|
success = modifyTopology(others[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Local vs. Global (already routed).
|
||||||
|
success = relax(_others[0],overlap);
|
||||||
|
if ( success ) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !success ) {
|
||||||
|
// Global vs. Local.
|
||||||
|
// Failed Local vs. Any.
|
||||||
|
success = modifyTopology(_segment);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secModifyTopology Description of the modifyTopology() method
|
||||||
|
*
|
||||||
|
\code
|
||||||
|
bool Manipulator::modifyTopology ( TrackSegment* segment )
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if ( segment->isLocal() ) {
|
||||||
|
if ( segment->canMinimize() {
|
||||||
|
segment->minimize();
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
if ( segment->canDogLeg() ) {
|
||||||
|
// Case -C.4- "Self Relax".
|
||||||
|
segment->makeDogLeg();
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
} else if ( segment->canDesalignate() ) {
|
||||||
|
// Case -C.5- "Desalignate".
|
||||||
|
segment->desalignate();
|
||||||
|
success = true;
|
||||||
|
} else if ( segment->canSlacken() ) {
|
||||||
|
// Case -C.6- "Slacken".
|
||||||
|
segment->slacken();
|
||||||
|
success = true;
|
||||||
|
} else {
|
||||||
|
RipupHistory* history = RipupHistory(segment);
|
||||||
|
GCell* dogLegGCell = history.getDogLegGCell();
|
||||||
|
|
||||||
|
if ( dogLegGCell ) {
|
||||||
|
if ( segment->canDogLegAt(dogLegGCell) ) {
|
||||||
|
segment->makeDogLeg(dogLegGCell)
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Dislodgers seems to far in ripup history.
|
||||||
|
// Recheck the Track, maybe they have vanish.
|
||||||
|
Track* track = getTrack(segment);
|
||||||
|
if ( track->getFreeInterval(segment) ) {
|
||||||
|
track.insert ( segment );
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( segment->canMoveUp() ) {
|
||||||
|
segment->moveUp ();
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( success ) {
|
||||||
|
resetRipupCount(segment);
|
||||||
|
} else {
|
||||||
|
cerr << "[UNIMPLEMENTED] " << segment << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secHardSoftOverlap Hard and soft overlap
|
||||||
|
*
|
||||||
|
* Schematic execution of a \RoutingEvent leading to a set aside.
|
||||||
|
* <ol>
|
||||||
|
* <li>The scheduler try to place the \TrackSegment on top of the
|
||||||
|
* event queue, calling process().
|
||||||
|
* <li>There is a soft overlap on the best candidate track, a set
|
||||||
|
* aside is issued.
|
||||||
|
* <li>Each \TrackSegment in conflict in the candidate track has the
|
||||||
|
* \RoutingEvent bounds of it's perpandicular \TrackSegment modificated
|
||||||
|
* according to the free space requested through setLeftBound() or setRightBound().
|
||||||
|
* <li>If a perpandicular is already in a \Track is removed from it and scheduled for
|
||||||
|
* immediate re-routing (it's event level is increased so it pops
|
||||||
|
* out immediately from the queue).
|
||||||
|
* <li>If the perpandicular is not routed yet, we are done.
|
||||||
|
*
|
||||||
|
* Note that this technique of modificating a \RoutingEvent yet to come is
|
||||||
|
* kind a like seeing the future...
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-3.png "Set aside schematic"
|
||||||
|
* \image latex RoutingEvent-3.pdf "Set aside schematic"
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section setDetructionStrategy Destruction Strategy
|
||||||
|
*
|
||||||
|
* \RoutingEvent are not destroyed as soon as they have been processed by
|
||||||
|
* the scheduler. Instead, they are stored in the historical queue.
|
||||||
|
* They are two reasons for that behavior :
|
||||||
|
* <ul>
|
||||||
|
* <li>\RoutingEvent are used to store algorithmic informations that
|
||||||
|
* must persist until the negociation algorithm have fully
|
||||||
|
* completed (<i>bound</i> interval in particular).
|
||||||
|
* <li>When ripup phases takes place and maximum ripup count is
|
||||||
|
* reached, the history can be used to find the whole set of
|
||||||
|
* \TrackSegment in conflict an made an educated guess about
|
||||||
|
* which one must be relaxed.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* \important This is the history queue which is responsible for freeing all the
|
||||||
|
* \RoutingEvent in his destructor.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secRoutingEventCase Routing Event actions
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li><b>Free Track Case</b>
|
||||||
|
*
|
||||||
|
* There is a sufficent free space in the candidate \Track to insert the
|
||||||
|
* \TrackSegment. The \TrackSegment is inserted.
|
||||||
|
*
|
||||||
|
* \important This is the only way for a \TrackSegment to be inserted into a \Track.
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-10.png
|
||||||
|
* \image latex RoutingEvent-10.pdf
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <li><b>Soft Overlap Case</b>
|
||||||
|
*
|
||||||
|
* Already inserted \TrackSegment <b>a</b> & <b>b</b> could be shrunk
|
||||||
|
* to make place for \TrackSegment <b>c</b>. Parallel overlaping \TrackSegment
|
||||||
|
* are not removed, their perpandiculars are with updated left/right axis weight.
|
||||||
|
*
|
||||||
|
* The <b>a</b> perpandicular belongs the same GCell routing set so it
|
||||||
|
* is removed from is \Track to be displaced.
|
||||||
|
*
|
||||||
|
* The <b>b</b> perdandicular belongs to a more prioritary GCell routing
|
||||||
|
* set, which has therefore be placed earlier so it can't be removed.
|
||||||
|
* Instead it is broken.
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-11.png
|
||||||
|
* \image latex RoutingEvent-11.pdf
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <li><b>Hard Overlap Case</b>
|
||||||
|
*
|
||||||
|
* No way to shrunk overlaping \TrackSegment to make place for <b>c</b>.
|
||||||
|
* All parallel overlaping \TrackSegments must be removeds to be displaced
|
||||||
|
* on other \Tracks.
|
||||||
|
*
|
||||||
|
* The <b>a</b> parallel belongs to a more prioritary GCell routing set
|
||||||
|
* so it can be removed, it is therefore broken.
|
||||||
|
*
|
||||||
|
* The <b>b</b> parallel belongs the same GCell routing set so it can be
|
||||||
|
* removed to be displaced.
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-12.png
|
||||||
|
* \image latex RoutingEvent-12.pdf
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <li><b>Self Relax</b>
|
||||||
|
*
|
||||||
|
* Instead of trying to displace overlaping \TrackSegments we break the
|
||||||
|
* current one.
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-13.png
|
||||||
|
* \image latex RoutingEvent-13.pdf
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <li><b>Self Desalignate</b>
|
||||||
|
*
|
||||||
|
* Instead of trying to displace overlaping \TrackSegments we desalignate
|
||||||
|
* it's components (by supressing alignement constraints on it's
|
||||||
|
* AutoContacts). We do not create new Katabatic components but new
|
||||||
|
* \TrackSegments will appears.
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-14.png
|
||||||
|
* \image latex RoutingEvent-14.pdf
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <li><b>Self Slacken</b>
|
||||||
|
*
|
||||||
|
* Instead of trying to displace overlaping \TrackSegments we slacken
|
||||||
|
* the current one. This is different than desalignate because we create
|
||||||
|
* new Katabatic component to relax any AutoContact transmitted constraints.
|
||||||
|
* This operation is most likely to be applied on \TrackSegments that are
|
||||||
|
* directly connecteds to terminals.
|
||||||
|
*
|
||||||
|
* \image html RoutingEvent-15.png
|
||||||
|
* \image latex RoutingEvent-15.pdf
|
||||||
|
*
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function bool RoutingEvent::isProcessed () const;
|
||||||
|
* \return \true if this event has already been processed.
|
||||||
|
*
|
||||||
|
* \remark Note that inside a _setAside() a \RoutingEvent can be re-posted for
|
||||||
|
* a given \TrackSegment which has been processed yet. This can lead
|
||||||
|
* to two or more \RoutingEvent in the queue (as we cannot easily remove
|
||||||
|
* a \RoutingEvent already in the queue). We need this new \RoutingEvent
|
||||||
|
* because we want to reschedule with a new priority/slack.
|
||||||
|
* As we cannot remove the previous \RoutingEvent, we mark it as
|
||||||
|
* processed for it to be ignored by the scheduler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function TrackSegment* RoutingEvent::getSegment () const;
|
||||||
|
* \Return The associated and unique \TrackSegment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function unsigned long RoutingEvent::getPriority () const;
|
||||||
|
* \Return The second criterion used to sort \RoutingEvents in the negociation queue.
|
||||||
|
* Currently, it is the <i>area</i> of the associated \TrackSegment, which in
|
||||||
|
* turn return the <i>slack</i> (not a very fortunate choice of name...).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function unsigned int RoutingEvent::getEventLevel () const;
|
||||||
|
* \Return The first criterion used to sort \RoutingEvents in the negociation queue.
|
||||||
|
* It is used to re-schedule a \RoutingEvent and make the new event be
|
||||||
|
* processed <i>before</i> the original one, which is marked as
|
||||||
|
* <i>processed</i> to be ignored.
|
||||||
|
*
|
||||||
|
* \see setEventLevel().
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function RoutingEvent* RoutingEvent::getClone () const;
|
||||||
|
* \Return An exact copy of the current \RoutingEvent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function RoutingEvent* RoutingEvent::reschedule ( RoutingEventQueue& queue );
|
||||||
|
* \param queue The \RoutingEvent queue.
|
||||||
|
* \return The rescheduled \RoutingEvent. May be \NULL if it cannot be rescheduled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function void RoutingEvent::setProcessed ( bool state=true );
|
||||||
|
* \param state The state into which the event is to be put.
|
||||||
|
*
|
||||||
|
* Mark the event as processed. This arises in two cases :
|
||||||
|
* <ul>
|
||||||
|
* <li>The event has really been processed by the process() member
|
||||||
|
* function.
|
||||||
|
* <li>There has been a fork from this event and it has been
|
||||||
|
* superseded by a newly rescheduled one, so we have to
|
||||||
|
* invalidate this one.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function void RoutingEvent::setEventLevel ( unsigned int level );
|
||||||
|
* \param level The new event level.
|
||||||
|
*
|
||||||
|
* \see getEventLevel().
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \function void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history );
|
||||||
|
* \param queue The event queue from the negociate algorithm.
|
||||||
|
* \param history The event history.
|
||||||
|
*
|
||||||
|
* Perform all the operations shared by all \RoutingEvent classes then
|
||||||
|
* calls the virtual _subProcess() functions.
|
||||||
|
*
|
||||||
|
* Shared operations are :
|
||||||
|
* <ol>
|
||||||
|
* <li>Invalidating all perpandicular \TrackSegments.
|
||||||
|
* <li>Computing the free interval allowed by the free intervals
|
||||||
|
* in perpandicular \Tracks holding the perpandicular \TrackSegments.
|
||||||
|
* <li>Merging in the various constraints intervals : from the
|
||||||
|
* \TrackSegment itself, from the free intervals in the
|
||||||
|
* perpandicular \Tracks and from the \RoutingEvent bound
|
||||||
|
* constraints.
|
||||||
|
* <li>Finding the candidate \Tracks for the \RoutingEvent,
|
||||||
|
* using \c Track_Spiral \Collection.
|
||||||
|
* </ol>
|
||||||
|
* The results of the shared operation are passed to derived classes
|
||||||
|
* trough the \c State internal structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* \function bool RoutingEvent::_setAside ( Track* track, size_t begin, size_t end, Net* net, Interval interval, RoutingEventQueue& queue );
|
||||||
|
* \param track The track in wich to make free space.
|
||||||
|
* \param begin The index of the first overlaping TrackSegment.
|
||||||
|
* \param end The index of the last overlaping TrackSegment.
|
||||||
|
* \param net The net for which we want to insert a TrackSegment.
|
||||||
|
* \param interval The interval which must be made empty.
|
||||||
|
* \param queue The queue of RoutingEvent.
|
||||||
|
*
|
||||||
|
* Manage the case of <i>soft overlap</i>. Create or enlarge a free space
|
||||||
|
* in \c track so it can contain the requested \interval. <code>[begin:end]</code> defines
|
||||||
|
* the range of indexes of overlaping \TrackSegment in \c track.
|
||||||
|
* Displace TrackSegment that are <b>perpandicular</b> to those overlaping,
|
||||||
|
* remove them from their \c Track if needed and issue an associated \RoutingEvent
|
||||||
|
* with an updated bound constraint. Note that the overlaping \TrackSegment
|
||||||
|
* themselves are <em>not</em> removed from the \c track.
|
||||||
|
*
|
||||||
|
* A note on implementation :
|
||||||
|
* <ul>
|
||||||
|
* <li>\c data1 : the DataNegociate of the to be inserted \TrackSegment.
|
||||||
|
* <li>\c segment2 : the current overlaping \TrackSegment (from \c begin
|
||||||
|
* to \c end).
|
||||||
|
* <li>\c data2 : the DataNegociate of the overlaping \TrackSegment.
|
||||||
|
* <li>\c segment3 : a \TrackSegment perpandicular to \c segment2.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* \function void RoutingEvent::_ripup ( Track* track, Net* net, Interval interval, size_t begin, size_t end, RoutingEventQueue& queue );
|
||||||
|
* \param track The track in wich to make free space.
|
||||||
|
* \param net The net for which we want to insert a TrackSegment.
|
||||||
|
* \param interval The interval which must be made empty.
|
||||||
|
* \param begin The index of the first overlaping TrackSegment.
|
||||||
|
* \param end The index of the last overlaping TrackSegment.
|
||||||
|
* \param queue The queue of RoutingEvent.
|
||||||
|
*
|
||||||
|
* Manage the case of <i>hard overlap</i>, that is bluntly remove
|
||||||
|
* any \TrackSegment overlaping \interval. Issue both a remove event
|
||||||
|
* (to \c Session) and a \RoutingEvent to re-process the dislodged
|
||||||
|
* \TrackSegment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // End of Kite namespace.
|
|
@ -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.
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
/*! \class RoutingEventLoop
|
||||||
|
* \brief Simple loop dectector for RoutingEvent.
|
||||||
|
*
|
||||||
|
* The RoutingEventLoop can be roughly understood as a truncated histogram
|
||||||
|
* of the \c depth last (in the time meaning) greatest riped up elements.
|
||||||
|
*
|
||||||
|
* The loop detector keep track of the \c depth TrackElement with the
|
||||||
|
* greatest processing count. TrackElement are just identified through
|
||||||
|
* the \c id of their associated AutoSegment. Each entry in the loop
|
||||||
|
* table contains:
|
||||||
|
* - The \c id of the associated TrackSegment (Katabatic::AutoSegment).
|
||||||
|
* - The \c count of times it has been processed
|
||||||
|
* - The \c timestamp of the latest time it has been updated.
|
||||||
|
*
|
||||||
|
* The table (implemented as \c vector<>) it kept sorted on the timestamp
|
||||||
|
* (decreasing). Whenever there is more than \c depth elements in the
|
||||||
|
* table, the oldest one are discarted (regardless of their count).
|
||||||
|
* Obviously, there are pathological cases into which a loop cannot
|
||||||
|
* be detected, but so far it has not happened so a more robust
|
||||||
|
* approach seems not necessary at this time.
|
||||||
|
*
|
||||||
|
* Whenever the count of an element reaches \c countLimit, the looping
|
||||||
|
* flag is set. It will remains set unless the faulty element is
|
||||||
|
* manually removed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function RoutingEventLoop::RoutingEventLoop ( size_t depth, int countLimit );
|
||||||
|
//! Construct a loop detector that handle \c depth differents segments
|
||||||
|
//! and has a looping threshold of \c countLimit.
|
||||||
|
|
||||||
|
//! \function bool RoutingEventLoop::isLooping () const;
|
||||||
|
//! \sreturn \true if the loop threshold has been reached for at least one
|
||||||
|
//! element.
|
||||||
|
|
||||||
|
//! \function int RoutingEventLoop::getMaxCount () const;
|
||||||
|
//! The maximal count an element as reached so far.
|
||||||
|
|
||||||
|
//! \function const std::vector<Element>& RoutingEventLoop::getElements () const;
|
||||||
|
//! The complete table elements.
|
||||||
|
|
||||||
|
//! \function void RoutingEventLoop::update ( size_t id ) ;
|
||||||
|
//! Update the loop, telling that element \c id has appreared one more
|
||||||
|
//! time.
|
||||||
|
|
||||||
|
//! \function void RoutingEventLoop::erase ( size_t id ) ;
|
||||||
|
//! Remove the entry related to element \c id in the table. The state of
|
||||||
|
//! the table is fully recomputed after the removal (looping flag &
|
||||||
|
//! maximum count).
|
||||||
|
//!
|
||||||
|
//! This method is used when a loop has been encountered, presumably on
|
||||||
|
//! element \c id, and we want to continue. To avoid the loop detector
|
||||||
|
//! yelling at each check, the associated TrackElement should be invalidated
|
||||||
|
//! and it's reference removed from the table.
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
/*! \class RoutingEventQueue
|
||||||
|
* \brief The priority Queue of RoutingEvent.
|
||||||
|
*
|
||||||
|
* \section secImplRoutingEventQueue Implementation Details
|
||||||
|
*
|
||||||
|
* The RoutingEventQueue is build upon a STL multiset<> and is sorted
|
||||||
|
* according to the RoutingEvent::Key attribute of the event. The key
|
||||||
|
* attribute has been designed specifically to be used with this queue.
|
||||||
|
* It provides the features:
|
||||||
|
* - Sort the RoutingEvent according to their priority. Higher priority
|
||||||
|
* mainly means more constrained segment, which must be routed first.
|
||||||
|
* - The attributes of RoutingEvent may change while inserted in the
|
||||||
|
* queue. The key provide a cached value of those attributes ensuring
|
||||||
|
* a stable sorting order.
|
||||||
|
*
|
||||||
|
* For more details about the sorting order, refer to RoutingEvent::Key.
|
||||||
|
*
|
||||||
|
* <b>Insertion, Reinsertion & Commit</b>
|
||||||
|
*
|
||||||
|
* When pushing a new event into the queue, the actual insertion into the
|
||||||
|
* multimap is delayed until the next call to \c RoutingEvent::commit().
|
||||||
|
* The to be inserted events are stored into a request set which is
|
||||||
|
* processed when commit is called. At commit time, the RoutingEvent::Key
|
||||||
|
* cache is updated just before inserting the element.
|
||||||
|
*
|
||||||
|
* When repushing an event, the event is immediatly withdrawn from the
|
||||||
|
* queue and put into the request set.
|
||||||
|
*
|
||||||
|
* <b>Mutiple Event for one Segment</b>
|
||||||
|
*
|
||||||
|
* As RoutingEvent can be cloned, there may be more than one event pointing
|
||||||
|
* to a segment. But there must be <em>only one active event</em>, the one
|
||||||
|
* which is pointed to by the segment. As a result, there maybe multiple
|
||||||
|
* events for an unique segment in the queue, but <em>only one active event</em>,
|
||||||
|
* the one that will be processed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function RoutingEventQueue::RoutingEventQueue ();
|
||||||
|
//! Contructor, create an empty queue.
|
||||||
|
|
||||||
|
//! \function RoutingEventQueue::~RoutingEventQueue ();
|
||||||
|
//! Destructor.
|
||||||
|
//!
|
||||||
|
//! \remark The destruction of the queue do not delete the
|
||||||
|
//! RoutingEvent that may still be in it (they shouldn't an
|
||||||
|
//! a warning is issued).
|
||||||
|
|
||||||
|
//! \function bool RoutingEventQueue::empty () const;
|
||||||
|
//! \sreturn \true if there is the queue is empty.
|
||||||
|
|
||||||
|
//! \function size_t RoutingEventQueue::size () const;
|
||||||
|
//! \sreturn The number of events in the queue.
|
||||||
|
|
||||||
|
//! \function unsigned int RoutingEventQueue::getTopEventLevel () const;
|
||||||
|
//! \sreturn The greatest event level the queue has ever reached (always increasing,
|
||||||
|
//! starting from zero).
|
||||||
|
|
||||||
|
//! \function void RoutingEventQueue::load ( const vector<TrackElement*>& );
|
||||||
|
//! Load a whole vector of TrackElement into the queue, for each
|
||||||
|
//! element:
|
||||||
|
//! - Create a RoutingEvent linked to the element.
|
||||||
|
//! \red{To be reviewed: replace any previous event.}
|
||||||
|
//! - Insert the new RoutingEvent into the queue.
|
||||||
|
//!
|
||||||
|
//! <em>No commit is needed after this operation.</em>
|
||||||
|
|
||||||
|
//! \function void RoutingEventQueue::add ( TrackElement* element, unsigned int level );
|
||||||
|
//! Create a new RoutingEvent in the queue with \c level, associated to \c element.
|
||||||
|
//! A commit is needed afterwards.
|
||||||
|
//!
|
||||||
|
//! \red{To be reviewed: replace any previous event on element.}
|
||||||
|
|
||||||
|
//! \function void RoutingEventQueue::push ( RoutingEvent* event );
|
||||||
|
//! Push a RoutingEvent in the queue. Effective only after the next commit.
|
||||||
|
|
||||||
|
//! \function RoutingEvent* RoutingEventQueue::pop ();
|
||||||
|
//! Remove the top element of the queue (i.e. the one with the highest
|
||||||
|
//! priority) and return it. If the queue is empty, \c NULL is returned.
|
||||||
|
|
||||||
|
//! \function void RoutingEventQueue::repush ( RoutingEvent* event );
|
||||||
|
//! Force a complete queue re-insertion for \c event. The event is immediatly
|
||||||
|
//! withdrawn from the queue and put into the insertion request set.
|
||||||
|
//!
|
||||||
|
//! If the \c event is not already in the queue, works like
|
||||||
|
//! RoutingEventQueue::push().
|
||||||
|
|
||||||
|
//! \function void RoutingEventQueue::repushInvalidateds ();
|
||||||
|
//! Using the list of invalidated segments from the Session, repush
|
||||||
|
//! them if:
|
||||||
|
//! - They have an associated event.
|
||||||
|
//! - The event is not \e unimplemented, \e disabled or \e processed.
|
||||||
|
|
||||||
|
//! \function void RoutingEventQueue::commit ();
|
||||||
|
//! Process the insertion request set and actually insert it's elements
|
||||||
|
//! into the queue. Perform a RoutingEvent::key update prior to insertion.
|
||||||
|
|
||||||
|
//! \function void RoutingEventQueue::clear ();
|
||||||
|
//! Empty the queue. Issue a warning if the queue is not empty (i.e. some
|
||||||
|
//! events remains to be processeds).
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
/*! \class RoutingPlane
|
||||||
|
* \brief Array of Tracks in one Layer
|
||||||
|
*
|
||||||
|
* A RoutingPlane is an array of Track covering a rectangular area.
|
||||||
|
* For now the area is the abutment box of the to be routed Cell.
|
||||||
|
* Tracks are spaced evenly and according to the configuration
|
||||||
|
* of the relevant RoutingLayerGauge.
|
||||||
|
*
|
||||||
|
* \image html RoutingPlane-1.png "Fig 1: Horizontal RoutingPlane"
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function RoutingPlane* RoutingPlane::create ( KiteEngine* engine, size_t depth );
|
||||||
|
//! \param engine The associated engine.
|
||||||
|
//! \param depth The Layer depth of the plane.
|
||||||
|
//! \return The newly created RoutingPlane.
|
||||||
|
//!
|
||||||
|
//! The RoutingPlane public constructor. The \c depth is in the sense of
|
||||||
|
//! the RoutingGauge.
|
||||||
|
|
||||||
|
//! \function bool RoutingPlane::isHorizontal () const;
|
||||||
|
//! \sreturn \true if the preferred routing direction is horizontal (the actual
|
||||||
|
//! direction of the tracks).
|
||||||
|
|
||||||
|
//! \function bool RoutingPlane::isVertical () const;
|
||||||
|
//! \sreturn \true if the preferred routing direction is vertical (the actual
|
||||||
|
//! direction of the tracks).
|
||||||
|
|
||||||
|
//! \function KiteEngine* RoutingPlane::getKiteEngine () const;
|
||||||
|
//! \sreturn The associated KiteEngine.
|
||||||
|
|
||||||
|
//! \function RoutingLayerGauge* RoutingPlane::getLayerGauge () const;
|
||||||
|
//! \sreturn The RoutingLayerGauge of the plane.
|
||||||
|
|
||||||
|
//! \function unsigned int RoutingPlane::getDirection () const;
|
||||||
|
//! \sreturn The preferred routing direction (Katabatic::KbHorizontal or Katabatic::KbVertical).
|
||||||
|
|
||||||
|
//! \function size_t RoutingPlane::getDepth () const;
|
||||||
|
//! \sreturn The depth of the associated layer (as defined by the RoutingLayerGauge).
|
||||||
|
|
||||||
|
//! \function size_t RoutingPlane::getAxisMin () const;
|
||||||
|
//! \sreturn The axis coordinate of the first/lowest track.
|
||||||
|
|
||||||
|
//! \function size_t RoutingPlane::getAxisMax () const;
|
||||||
|
//! \sreturn The axis coordinate of the last/highest track.
|
||||||
|
|
||||||
|
//! \function size_t RoutingPlane::getTrackMin () const;
|
||||||
|
//! \sreturn The minimum bound of all track.
|
||||||
|
|
||||||
|
//! \function size_t RoutingPlane::getTrackMax () const;
|
||||||
|
//! \sreturn The maximum bound of all track.
|
||||||
|
|
||||||
|
//! \function RoutingPlane* RoutingPlane::getTop () const;
|
||||||
|
//! \sreturn The RoutingPlane immediatly above this one.
|
||||||
|
|
||||||
|
//! \function RoutingPlane* RoutingPlane::getBottom () const;
|
||||||
|
//! \sreturn The RoutingPlane immediatly below this one.
|
||||||
|
|
||||||
|
//! \function const Layer* RoutingPlane::getLayer () const;
|
||||||
|
//! \sreturn The associated routing layer.
|
||||||
|
|
||||||
|
//! \function const Layer* RoutingPlane::getBlockageLayer () const;
|
||||||
|
//! \sreturn The blockage layer associated to the routing layer.
|
||||||
|
|
||||||
|
//! \function size_t RoutingPlane::getTracksSize () const;
|
||||||
|
//! \sreturn The number of tracks in the array.
|
||||||
|
|
||||||
|
//! \function size_t RoutingPlane::computeTracksSize () const;
|
||||||
|
//! \sreturn The number of tracks <em>to create</em> in the array.
|
||||||
|
//!
|
||||||
|
//! Helper method that compute the number of tracks in the array
|
||||||
|
//! from the area of the Cell to be routed and the RoutingLayerGauge
|
||||||
|
//! characteristics (the Cell is accessible through the KiteEngine).
|
||||||
|
|
||||||
|
//! \function DbU::Unit RoutingPlane::getTrackPosition ( size_t index ) const;
|
||||||
|
//! \sreturn The axis of the track at \c index in the array.
|
||||||
|
|
||||||
|
//! \function Track* RoutingPlane::getTrackByIndex ( size_t index ) const;
|
||||||
|
//! \sreturn The track at \c index in the array.
|
||||||
|
|
||||||
|
//! \function Track* RoutingPlane::getTrackByPosition ( DbU::Unit axis, unsigned int mode=KtNearest ) const;
|
||||||
|
//! \sreturn The track which position is nearest from \c axis. The meaning of
|
||||||
|
//! \e nearest is defined by \c mode (classic rouding options).
|
||||||
|
|
||||||
|
//! \function bool RoutingPlane::_check ( unsigned int& overlaps ) const;
|
||||||
|
//! \sreturn \true if no errors have been found (i.e. the database is coherent).
|
||||||
|
//!
|
||||||
|
//! Perform a coherency check on all tracks part of the array.
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,474 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Class : "SegmentAction".
|
||||||
|
|
||||||
|
/*! \class SegmentAction
|
||||||
|
* \brief Store request for an event to be generated on a TrackElement
|
||||||
|
*
|
||||||
|
* When an event on a Kite::TrackElement is being processed (with the
|
||||||
|
* SegmentFsm helper), it may generate events on TrackElement already
|
||||||
|
* placed and belonging either to the same net or other ones.
|
||||||
|
* Those events are not generated and queued immediatly but
|
||||||
|
* instead SegmentAction, requesting the event generation are created
|
||||||
|
* and stored into a simple vector in SegmentFsm. The last operation of
|
||||||
|
* the SegmentFsm object is to call the SegmentAction::doAction() method
|
||||||
|
* on all the action to actually generate and queue the events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \enum SegmentAction::Type
|
||||||
|
//! Indicates the kind of action to be performed on the segment. In the following
|
||||||
|
//! \b flags and \b masks descriptions, we uses the term <em>reference segment</em>
|
||||||
|
//! for the TrackElement which is associated with the currently processed RoutingEvent
|
||||||
|
//! (also referenced in SegmentFsm).
|
||||||
|
//!
|
||||||
|
//! Here is the list of the availables actions that can be performed when (re)scheduling
|
||||||
|
//! a RoutingEvent. It is here that we uses the RoutingEvent level feature to perform
|
||||||
|
//! a local reordering of the top of the queue. Reordering is used to allows
|
||||||
|
//! perpandiculars to be routed \e before the reference segment (instead of after)
|
||||||
|
//! or \e other segments in conflict.
|
||||||
|
//!
|
||||||
|
//! - SegmentAction::SelfInsert<br>
|
||||||
|
//! <b>Action:</b> The reference segment is to be inserted in a Track (placed).<br>
|
||||||
|
//! <b>Event Level:</b> Unchanged.
|
||||||
|
//!
|
||||||
|
//! - SegmentAction::SelfRipup<br>
|
||||||
|
//! <b>Action:</b> The reference segment is to be ripped up.<br>
|
||||||
|
//! <b>Event Level:</b> Unchanged.
|
||||||
|
//!
|
||||||
|
//! - SegmentAction::SelfRipupPerpand<br>
|
||||||
|
//! <b>Action:</b> Ripup a segment which is a perpandicular to the reference
|
||||||
|
//! segment. Ordering considerations: this perpandicular will be put back into
|
||||||
|
//! the RoutingEvent queue with a lower level (priority) than the reference
|
||||||
|
//! segment, so it will be processed again \e after the reference segment.<br>
|
||||||
|
//! <b>Event Level:</b> Unchanged.
|
||||||
|
//!
|
||||||
|
//! - SegmentAction::SelfRipupPerpandWithAxisHint<br>
|
||||||
|
//! <b>Action:</b> Ripup a segment which is a perpandicular to the reference
|
||||||
|
//! segment, supplies an axis hint and put it back into the RoutingEvent queue so
|
||||||
|
//! that it will be processed \e before the reference segment.<br>
|
||||||
|
//! <b>Event Level:</b> Increased to SegmentAction::EventLevel4.
|
||||||
|
//!
|
||||||
|
//! - SegmentAction::OtherRipup<br>
|
||||||
|
//! <b>Action:</b> Ripping up a segment from another net and in the same direction
|
||||||
|
//! as the reference segment.<br>
|
||||||
|
//! <b>Event Level:</b> Unchanged.
|
||||||
|
//!
|
||||||
|
//! - SegmentAction::OtherRipupPerpandAndPushAside<br>
|
||||||
|
//! <b>Action:</b> Ripping up a segment from another net and in perpandicular
|
||||||
|
//! direction. The level is elevated so it's priority is greater than the
|
||||||
|
//! reference segment this it will be reprocessed first. An axis hint is also
|
||||||
|
//! supplied in order to make room for the reference segment.<br>
|
||||||
|
//! <b>Event Level:</b> Increased to SegmentAction::EventLevel3.
|
||||||
|
//!
|
||||||
|
//! - SegmentAction::OtherRipupPerpandAndPacking<br>
|
||||||
|
//! <b>Action:</b> Ripping up a segment from another net and in perpandicular
|
||||||
|
//! direction. The level is elevated so it's priority is greater than the
|
||||||
|
//! reference segment this it will be reprocessed first. The generated event
|
||||||
|
//! is in packing mode only.<br>
|
||||||
|
//! <b>Event Level:</b> Increased to SegmentAction::EventLevel4.
|
||||||
|
|
||||||
|
//! \var SegmentAction::Self
|
||||||
|
//! <b>[Flag]</b> The segment associated to the action is the reference segment
|
||||||
|
//! <em>or segments from the same net</em>.
|
||||||
|
|
||||||
|
//! \var SegmentAction::Other
|
||||||
|
//! <b>[Flag]</b> The segment associated to the action is \b not from the same
|
||||||
|
//! net as the reference segment.
|
||||||
|
|
||||||
|
//! \var SegmentAction::Perpandicular
|
||||||
|
//! <b>[Flag]</b> The action concern a perpandicular to the reference segment.
|
||||||
|
|
||||||
|
//! \var SegmentAction::Ripup
|
||||||
|
//! <b>[Flag]</b> Request that the segment is to be ripped up.
|
||||||
|
|
||||||
|
//! \var SegmentAction::RipedByLocal
|
||||||
|
//! <b>[Flag]</b> Indicate that the segment has been ripped up by a local one.
|
||||||
|
|
||||||
|
//! \var SegmentAction::ResetRipup
|
||||||
|
//! <b>[Flag]</b> The ripup count is to be reset.
|
||||||
|
|
||||||
|
//! \var SegmentAction::ToRipupLimit
|
||||||
|
//! <b>[Flag]</b> The ripup count is directly increased to the ripup limit,
|
||||||
|
//! triggering a state change the next time the segment will be processed.
|
||||||
|
|
||||||
|
//! \var SegmentAction::Insert
|
||||||
|
//! <b>[Flag]</b> Request that the segment is to be inserted in the given track.
|
||||||
|
//! It is the task of SegmentFsm to determine that there is sufficent space to do so.
|
||||||
|
|
||||||
|
//! \var SegmentAction::AxisHint
|
||||||
|
//! <b>[Flag]</b> An axis hint has been supplied, and is to be passed to
|
||||||
|
//! the generated RoutingEvent.
|
||||||
|
|
||||||
|
//! \var SegmentAction::PackingMode
|
||||||
|
//! <b>[Flag]</b> Whether the RoutingEvent should be processed in \e packing
|
||||||
|
//! mode or \e negociated mode (transmitted to the RoutingEvent).
|
||||||
|
|
||||||
|
//! \var SegmentAction::ToState
|
||||||
|
//! <b>[Flag]</b> Force the change of state of the RoutingEvent
|
||||||
|
//! (i.e. DataNegociate). Normally the state change is done through the
|
||||||
|
//! increase of the ripup count in DataNegociate.
|
||||||
|
|
||||||
|
//! \var SegmentAction::EventLevel1
|
||||||
|
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 1.
|
||||||
|
|
||||||
|
//! \var SegmentAction::EventLevel2
|
||||||
|
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 2.
|
||||||
|
|
||||||
|
//! \var SegmentAction::EventLevel3
|
||||||
|
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 3.
|
||||||
|
|
||||||
|
//! \var SegmentAction::EventLevel4
|
||||||
|
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 4.
|
||||||
|
|
||||||
|
//! \var SegmentAction::EventLevel5
|
||||||
|
//! <b>[Flag]</b> Increase the level to <em>at least</em> \b 5.
|
||||||
|
|
||||||
|
//! \var SegmentAction::SelfInsert
|
||||||
|
//! <b>[Mask]</b>, see SegmentAction::Type.
|
||||||
|
|
||||||
|
//! \var SegmentAction::SelfRipup
|
||||||
|
//! <b>[Mask]</b>, see SegmentAction::Type.
|
||||||
|
|
||||||
|
//! \var SegmentAction::SelfRipupPerpand
|
||||||
|
//! <b>[Mask]</b>, see SegmentAction::Type.
|
||||||
|
|
||||||
|
//! \var SegmentAction::SelfRipupPerpandWithAxisHint
|
||||||
|
//! <b>[Mask]</b>, see SegmentAction::Type.
|
||||||
|
|
||||||
|
//! \var SegmentAction::OtherRipup
|
||||||
|
//! <b>[Mask]</b>, see SegmentAction::Type.
|
||||||
|
|
||||||
|
//! \var SegmentAction::OtherRipupPerpandAndPushAside
|
||||||
|
//! <b>[Mask]</b>, see SegmentAction::Type.
|
||||||
|
|
||||||
|
//! \var SegmentAction::OtherRipupPerpandAndPacking
|
||||||
|
//! <b>[Mask]</b>, see SegmentAction::Type.
|
||||||
|
|
||||||
|
//! \function SegmentAction::SegmentAction ( TrackElement* segment, unsigned int type, DbU::Unit axisHint=0, unsigned int toState =0 );
|
||||||
|
//! \param segment On what the action is to be performed.
|
||||||
|
//! \param type Defines the type of action, see SegmentAction::Type.
|
||||||
|
//! \param axisHint Specifies a preferred axis.
|
||||||
|
//! \param toState The DataNegociate::SlackState into which the segment is to be set.
|
||||||
|
//!
|
||||||
|
//! Create segment action.
|
||||||
|
|
||||||
|
//! \function TrackElement* SegmentAction::getSegment () const;
|
||||||
|
//! \sreturn The associated \c segment.
|
||||||
|
|
||||||
|
//! \function SegmentAction::Type SegmentAction::getType () const;
|
||||||
|
//! \sreturn The action to be performed.
|
||||||
|
|
||||||
|
//! \function void SegmentAction::setAxisHint ( DbU::Unit axis );
|
||||||
|
//! The axis preferred position to be transmitted to the generated event.
|
||||||
|
//! The transmition will be effective \e only if the SegmentAction::Type::AxisHint
|
||||||
|
//! flag is set.
|
||||||
|
|
||||||
|
//! \function unsigned int SegmentAction::setFlag ( unsigned int flags );
|
||||||
|
//! Allow to change the action type by indivually setting up the flags.
|
||||||
|
|
||||||
|
//! \function void SegmentAction::doAction ( RoutingEventQueue& queue );
|
||||||
|
//! Actually perform the action. That is, build and queue the appropriate
|
||||||
|
//! event for the segment.
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Class : "SegmentFsm".
|
||||||
|
|
||||||
|
/*! \class SegmentFsm
|
||||||
|
* \brief Pseudo-decorator to process a RoutingEvent
|
||||||
|
*
|
||||||
|
* The SegmentFsm class actually perform the placement of the Kite::TrackElement
|
||||||
|
* of the Kite::RoutingEvent. It structured around three goals:
|
||||||
|
* - Implement the finite state machine for the Kite::DataNegociate state.
|
||||||
|
* - Provide a kind of decoration on the RoutingEvent/TrackElement
|
||||||
|
* (it do not abide by the definition from Design Patterns).
|
||||||
|
* - Cache a lot of on-the-fly computed datas needed during the
|
||||||
|
* SegmentFsm lifetime and the Manipulator(s) it may uses.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secUpdate Update Mechanism
|
||||||
|
*
|
||||||
|
* The constructor of SegmentFsm triggers the update of the RoutingEvent
|
||||||
|
* and through it DataNegociate.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secSlackening Slackening / FSM Transitions
|
||||||
|
*
|
||||||
|
* A transition occurs in the FSM whenener all the availables ripup methods
|
||||||
|
* for a segment have failed. Failure means that the topology of the net
|
||||||
|
* itself must be altered to allow a greater level of flexibility.
|
||||||
|
* Modifying the net topology means to give the current segment some
|
||||||
|
* more slack.
|
||||||
|
*
|
||||||
|
* Availables slackening operations:
|
||||||
|
* -# DataNegociate::RipupPerpandiculars (Manipulator) place the segments before any of
|
||||||
|
* it's perpandiculars are placed to allow a maximum track choice.
|
||||||
|
* -# DataNegociate::Minimize (Manipulator) try to fit the segment in a hole in a track,
|
||||||
|
* perform a hole detection.
|
||||||
|
* -# DataNegociate::Dogleg (Manipulator) create a dogleg matching <em>the first track
|
||||||
|
* candidate</em> with a non-nul overlap.
|
||||||
|
* -# DataNegociate::Slacken (Manipulator) \red{to be reviewed.}
|
||||||
|
* -# DataNegociate::ConflictSolveByHistory (SegmentFsm) try to find a break point on
|
||||||
|
* the segment, based on the ripup history.
|
||||||
|
* -# DataNegociate::ConflictSolveByPlaceds (SegmentFsm) try to find a break point on
|
||||||
|
* the segment, based on the current position of segments on the
|
||||||
|
* candidate tracks.
|
||||||
|
* -# DataNegociate::MoveUp (Manipulator) try to move up the segment.
|
||||||
|
*
|
||||||
|
* Simple slackening operations are defined in Manipulator and complex ones
|
||||||
|
* directly in SegmentFsm.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secNonSlackening Non-Slackening Operations
|
||||||
|
*
|
||||||
|
* In addition, some operation that do not modifies the topology are
|
||||||
|
* availables:
|
||||||
|
* -# Manipulator::forceOverLocals() mostly for global segments to ripup
|
||||||
|
* a track from all it's locals.
|
||||||
|
* -# SegmentFsm::insertInTrack() automates the three subsequent ripup
|
||||||
|
* trials.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \enum SegmentFsm::State
|
||||||
|
//! Indicates what the SegmentFsm has done the processed TrackElement,
|
||||||
|
//! possible values are:
|
||||||
|
//! - SegmentFsm::MissingData, this is an error condition, the TrackElement
|
||||||
|
//! do not have associated DataNegociate structure. Nothing is done.
|
||||||
|
//!
|
||||||
|
//! - SegmentFsm::EmptyTrackList, no Track is available for placement
|
||||||
|
//! (free or used).
|
||||||
|
//!
|
||||||
|
//! - SegmentFsm::SelfInserted, the TrackElement can be successfully
|
||||||
|
//! inserted in a Track (i.e. without overlap).
|
||||||
|
//!
|
||||||
|
//! - SegmentFsm::SelfMaximumSlack, nothing can be done to further slacken
|
||||||
|
//! the TrackElement, it is at maximum ripup of the last possible state
|
||||||
|
//! (no more topological modifications are possibles).
|
||||||
|
//!
|
||||||
|
//! - SegmentFsm::OtherRipup, the TrackElement can be inserted but it
|
||||||
|
//! needs the ripup of some others.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::MissingData
|
||||||
|
//! <b>[Flag]</b>, see SegmentFsm::SegmentFsmValue.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::EmptyTrackList
|
||||||
|
//! <b>[Flag]</b>, see SegmentFsm::SegmentFsmValue.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::Inserted
|
||||||
|
//! <b>[Flag]</b>, the TrackElement can be inserted in a Track.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::Self
|
||||||
|
//! <b>[Flag]</b>, the action is related to the processed TrackSegment.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::Other
|
||||||
|
//! <b>[Flag]</b>, the action is \b not related to the processed TrackSegment,
|
||||||
|
//! that is, others are being topologically modificated or riped up.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::Ripup
|
||||||
|
//! <b>[Flag]</b>, segement, that are not the processed one are being ripped up.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::MaximumSlack
|
||||||
|
//! <b>[Flag]</b>, the processed segment as reached it's maximum ripup count on
|
||||||
|
//! the last possible slackening state.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::SelfInserted
|
||||||
|
//! <b>[Mask]</b>, see SegmentFsm::SegmentFsmValue.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::OtherRipup
|
||||||
|
//! <b>[Mask]</b>, see SegmentFsm::SegmentFsmValue.
|
||||||
|
|
||||||
|
//! \var SegmentFsm::SelfMaximumSlack
|
||||||
|
//! <b>[Mask]</b>, see SegmentFsm::SegmentFsmValue.
|
||||||
|
|
||||||
|
//! \function SegmentFsm::SegmentFsm ( RoutingEvent* event, RoutingEventQueue& queue, RoutingEventHistory& history );
|
||||||
|
//! \param event The RoutingEvent to be processed.
|
||||||
|
//! \param queue The RoutingEvent queue.
|
||||||
|
//! \param history The complete history of RoutingEvent.
|
||||||
|
//!
|
||||||
|
//! Construct a SegmentFsm from a RoutingEvent. The constructor is in charge of
|
||||||
|
//! computing all the cached values.
|
||||||
|
|
||||||
|
//! \function bool SegmentFsm::isFullBlocked () const;
|
||||||
|
//! \sreturn \true if there are Tracks avalaibles but the constraints are such that none
|
||||||
|
//! is actually usable.
|
||||||
|
|
||||||
|
//! \function RoutingEvent* SegmentFsm::getEvent () const;
|
||||||
|
//! \sreturn The currently processed RoutingEvent (\e cached).
|
||||||
|
|
||||||
|
//! \function RoutingEventQueue& SegmentFsm::getQueue () const;
|
||||||
|
//! \sreturn The RoutingEvent queue (\e cached).
|
||||||
|
|
||||||
|
//! \function RoutingEventHistory& SegmentFsm::getHistory () const;
|
||||||
|
//! \sreturn The RoutingEvent history (\e cached).
|
||||||
|
|
||||||
|
//! \function DataNegociate* SegmentFsm::getData ();
|
||||||
|
//! \sreturn The DataNegociate of the TrackElement (\e cached).
|
||||||
|
|
||||||
|
//! \function unsigned int SegmentFsm::getState () const;
|
||||||
|
//! \sreturn The state (SegmentFsm::SegmentFsmValues) which the SegmentFsm has computed for the
|
||||||
|
//! RoutingEvent. This is \b not the state of the DataNegociate
|
||||||
|
|
||||||
|
//! \function Interval& SegmentFsm::getConstraint ();
|
||||||
|
//! \sreturn The interval into which the segment axis can be set (computed from
|
||||||
|
//! the topological constraints and the placement constraints on the
|
||||||
|
//! already placed perpandiculars).
|
||||||
|
|
||||||
|
//! \function Interval& SegmentFsm::getOptimal ();
|
||||||
|
//! \sreturn The interval for an optimal placement of the segment axis.
|
||||||
|
|
||||||
|
//! \function vector<TrackCost>& SegmentFsm::getCosts ();
|
||||||
|
//! \sreturn The table of cost for all the candidates Tracks of the segment.
|
||||||
|
//! The table is sorted in increasing cost order (see TrackCost).
|
||||||
|
|
||||||
|
//! \function TrackCost& SegmentFsm::getCost ( size_t i );
|
||||||
|
//! \sreturn The cost at index \c i in the table.
|
||||||
|
|
||||||
|
//! \function Track* SegmentFsm::getTrack ( size_t i );
|
||||||
|
//! \sreturn The Track for cost at index \c i in the table.
|
||||||
|
|
||||||
|
//! \function size_t SegmentFsm::getBegin ( size_t i );
|
||||||
|
//! \sreturn The overlapping \e begin index in Track for cost at index \c i in the table.
|
||||||
|
|
||||||
|
//! \function size_t SegmentFsm::getEnd ( size_t i );
|
||||||
|
//! \sreturn The overlapping \e end index in Track for cost at index \c i in the table.
|
||||||
|
|
||||||
|
//! \function vector<SegmentAction*>& SegmentFsm::getActions ();
|
||||||
|
//! \sreturn The table of SegmentAction, that is the delayed requests for RoutingEvent
|
||||||
|
//! creation.
|
||||||
|
|
||||||
|
//! \function unsigned int SegmentFsm::setState ( unsigned int state );
|
||||||
|
//! \sreturn Sets the state of the state...
|
||||||
|
|
||||||
|
//! \function void SegmentFsm::addAction ( TrackElement* segment, unsigned int type, DbU::Unit axisHint=0, unsigned int toState=0 );
|
||||||
|
//! Request the creation of a new delayed RoutingEvent, for the meaning of
|
||||||
|
//! the parameters, see SegmentAction::SegmentAction.
|
||||||
|
|
||||||
|
//! \function bool SegmentFsm::doActions ();
|
||||||
|
//! Actually generate RoutingEvent(s) from the SegmentAction(s).
|
||||||
|
|
||||||
|
//! \function void SegmentFsm::clearActions ();
|
||||||
|
//! Clear the the table of requested actions, whithout generating them.
|
||||||
|
|
||||||
|
//! \function void SegmentFsm::clearActions ();
|
||||||
|
//! Clear the the table of requested actions, whithout generating them.
|
||||||
|
|
||||||
|
//! \function bool SegmentFsm::insertInTrack ( size_t i );
|
||||||
|
//! Try to insert the TrackElement in the Track at index \c i (in the
|
||||||
|
//! cost table). Return \true if the insertion is possible.
|
||||||
|
//!
|
||||||
|
//! The insertion is not done at this stage, but a set of ripup actions is
|
||||||
|
//! emitted to allow insertion the next time the segment will be processed.
|
||||||
|
//!
|
||||||
|
//! Three subsequent trials are done before giving up on inserting
|
||||||
|
//! the segment:
|
||||||
|
//! -# Manipulator::insertInTrack(), try to push asides the neighbors.
|
||||||
|
//! -# Manipulator::shrinkToTrack(), try squeeze the segment in an existing
|
||||||
|
//! free space.
|
||||||
|
//! -# Manipulator::forceToTrack(), perform a complete ripup of all the
|
||||||
|
//! neighbors and their perpandiculars.
|
||||||
|
//!
|
||||||
|
//! The event keeps track of the insertion attempt step (see RoutingEvent::getInsertState()).
|
||||||
|
|
||||||
|
//! \function bool SegmentFsm::conflictSolveByHistory ();
|
||||||
|
//! \sreturn \true if a suitable dogleg has been created in the segment.
|
||||||
|
//!
|
||||||
|
//! Initially, global segments may be very long, and a placement solution
|
||||||
|
//! in which each one is placed on a track of it's own may not be realisable.
|
||||||
|
//! In that case, at least one of the global segment must be broken.
|
||||||
|
//! The figure below illustrate the case: <b>(a)</b>, <b>(b)</b>, <b>(c)</b> form a
|
||||||
|
//! first cluster and <b>(d)</b>, <b>(e)</b>, <b>(f)</b> form a second one. Due to the
|
||||||
|
//! constraints of the segments the remaining free track cannot be the same
|
||||||
|
//! in both clusters. The only solution to place <b>(g)</b> is to break it into
|
||||||
|
//! two sub-globals. The whole point of the conflict solve is to correctly
|
||||||
|
//! detect the cluster and choose the breaking point.
|
||||||
|
//!
|
||||||
|
//! \image html ConflictSolve-1.png "Conflict Between Globals"
|
||||||
|
//!
|
||||||
|
//! This variant of the conflict solve method try to guess the track span
|
||||||
|
//! for which there is a conflict by looking at the event history.
|
||||||
|
//!
|
||||||
|
//! \image html ConflictSolveByHistory-1.png "Building Conflicting Intervals"
|
||||||
|
//!
|
||||||
|
//! <b>Dislodger Definition:</b>
|
||||||
|
//!
|
||||||
|
//! A segment is said to be a dislodger if it matches the two following criterions:
|
||||||
|
//! - It's span intersect the to be inserted segment span.
|
||||||
|
//! - It has been placed on a track inside the perpandicular span of the
|
||||||
|
//! to be placed segment.
|
||||||
|
//!
|
||||||
|
//! For the time beeing we limit the search to the last three dislodgers, to not
|
||||||
|
//! waste too much time looking back the event history. We merge overlapping
|
||||||
|
//! intervals into one (see the undocumented class \c UnionIntervals and
|
||||||
|
//! \c RipupHistory in \c SegmentFsm.cpp).
|
||||||
|
//!
|
||||||
|
//! \red{For the time beeing we only look on the track into which}
|
||||||
|
//! \red{the to be inserted segment wants to be placed.}
|
||||||
|
//!
|
||||||
|
//! Then we try to break the to be placed segment, first under the lower bound
|
||||||
|
//! (source) of the conflicting interval then, in case of failure under
|
||||||
|
//! the upper bound (target).
|
||||||
|
//!
|
||||||
|
//! \image html ConflictSolveByHistory-2.png "Interval Breaking"
|
||||||
|
|
||||||
|
//! \function bool SegmentFsm::conflictSolveByPlaceds ();
|
||||||
|
//! \sreturn \true if a suitable dogleg has been created in the segment \e or a
|
||||||
|
//! dislodger has been moved up.
|
||||||
|
//!
|
||||||
|
//! This methods achieve the same goal as SegmentFsm::conflictSolveByHistory()
|
||||||
|
//! but uses a different strategy.
|
||||||
|
//!
|
||||||
|
//! Instead of looking through the history to find dislodgers it analyses
|
||||||
|
//! the placed segments in all the candidates tracks for the to be placed
|
||||||
|
//! segment. Unlike it's sibling method, which creates only one dogleg, as
|
||||||
|
//! it uses the Manipulator::relax() method, it may creates up to two doglegs.
|
||||||
|
//!
|
||||||
|
//! <b>Synthetic Description</b>
|
||||||
|
//!
|
||||||
|
//! -# For each track, find the dislodgers, merge the overlaps into one
|
||||||
|
//! interval and store the length of the longuest overlap (aka conflict).
|
||||||
|
//! -# Sort the tracks according to decreasing longuest overlap/confict.
|
||||||
|
//! -# For each track in the sorted list, look for a dislodger under the middle
|
||||||
|
//! of the to be placed segment. If no dislodger is present at this place
|
||||||
|
//! go to the next track. Otherwise:
|
||||||
|
//! - <em>The dislodger is local</em>, then try to relax the to placed
|
||||||
|
//! segment around the dislodger.
|
||||||
|
//! - <em>The dislodger is global</em>, try to move it up, if it is not
|
||||||
|
//! possible, fallback to the relax approach.
|
||||||
|
//! -# Quit on the first successful move up or relax.
|
||||||
|
//! -# If there is no candidate tracks, this means the vertical constraints
|
||||||
|
//! are too tight, in that case, ripup the perpandiculars (fallback plan).
|
||||||
|
//!
|
||||||
|
//! <b>Interval Accounting</b>
|
||||||
|
//!
|
||||||
|
//! Only global conflicting segments are took into account. Local segments
|
||||||
|
//! may be took into account if they overlap global ones (all part of the
|
||||||
|
//! same net). All overlapping segments are merged into one big conflict
|
||||||
|
//! interval. The whole length of a conflict interval is took into account
|
||||||
|
//! event if it's overlap with the to be placed segment is only partial.
|
||||||
|
//!
|
||||||
|
//! <b>Track Ordering (lexicographic)</b>
|
||||||
|
//!
|
||||||
|
//! -# The longuest (in one interval) conflict length.
|
||||||
|
//! -# The longuest cumulative conflict length (all interval summed up).
|
||||||
|
//!
|
||||||
|
//! Interval accounting and Track ordering is managed through the undocumented
|
||||||
|
//! \c Cs1Candidate class implemented in \c SegmentFsm.cpp.
|
||||||
|
//!
|
||||||
|
//! \image html ConflictSolveByPlaceds-1.png "Candidates Track Ordering"
|
||||||
|
|
||||||
|
//! \function bool SegmentFsm::desaturate ();
|
||||||
|
//! Try to create a suitable empty space in a cost Track by moving up
|
||||||
|
//! TrackElement in conflict.
|
||||||
|
|
||||||
|
//! \function bool SegmentFsm::slackenTopology ( unsigned int flags=0 );
|
||||||
|
//! Modificate the topology of the TrackElement to slacken it.
|
||||||
|
//! It is the implementation of the slakening finite state machine.
|
||||||
|
|
||||||
|
//! \function bool SegmentFsm::solveFullBlockages ();
|
||||||
|
//! Try to solve a fully blocked configuration.
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,308 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
//! \typedef SegmentOverlapCostCB
|
||||||
|
//! Prototype of overlap cost callback functions.
|
||||||
|
//!
|
||||||
|
//! \sa TrackSegment::setOverlapCostCB(), TrackSegment::getOverlapCost().
|
||||||
|
|
||||||
|
/*! \class TrackElement
|
||||||
|
*
|
||||||
|
* \brief Abstract Class for all Elements inserted inside a Track.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secTrackElementAbstract TrackElement Abstract
|
||||||
|
*
|
||||||
|
* The TrackElement class is abstract and is used as base class for
|
||||||
|
* any element that can be inserted in a Track. It represent the
|
||||||
|
* footprint of that element inside the Track (an interval).
|
||||||
|
* Additionnaly it keep a pointer to the Track and it's index inside
|
||||||
|
* it (Track is implemented with a \c vector<>).
|
||||||
|
*
|
||||||
|
* To avoid some explicit dynamic cast later, it provides a default
|
||||||
|
* implementation for almost all the methods that will be present
|
||||||
|
* in all the derived classes. All default methods return \c false,
|
||||||
|
* \c NULL or \c 0 (\e zero) or whatever is appropriated to tell
|
||||||
|
* it is not meaningful.
|
||||||
|
*
|
||||||
|
* <b>Design Note</b>
|
||||||
|
*
|
||||||
|
* TrackElement has been designed to serve as a base class for TrackSegment
|
||||||
|
* and TrackMarker. But, in the end, those two classes have been put in
|
||||||
|
* separated vectors inside the Track, thus rendering this design choice
|
||||||
|
* less pertinent. We keep it for now because we may introduce other
|
||||||
|
* object than TrackSegment inside a Track. If the need do not arise,
|
||||||
|
* we may merge back TrackElement and TrackSegment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isFixed() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isFixed().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isHorizontal() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isHorizontal().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isVertical() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isVertical().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isLocal() const;
|
||||||
|
//! \sa Katabatic::isLocal().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isGlobal() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isGlobal().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isBipoint() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isBipoint().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isTerminal() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isTerminal().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isStrap() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isStrap().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isSlackened() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isSlackened().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isDogleg() const;
|
||||||
|
//! \sa Katabatic::isDogleg().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isInvalidated() const;
|
||||||
|
//! \sreturn \true if the segment is invalidated (may be different from
|
||||||
|
//! the supporting AutoSegment status).
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isCreated() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::isCreated().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isBlockage() const;
|
||||||
|
//! \true if the element is a blockage (obstacle).
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isLocked() const;
|
||||||
|
//! \true if the element is part of a net, but must not be
|
||||||
|
//! moved by the router, whatever the reason.
|
||||||
|
|
||||||
|
//! \function bool TrackElement::isRouted() const;
|
||||||
|
//! \true if the router has placed it.
|
||||||
|
|
||||||
|
//! \function bool TrackElement::hasSourceDogleg() const;
|
||||||
|
//! \red{This method purpose has not been reviewed yet}.
|
||||||
|
|
||||||
|
//! \function bool TrackElement::hasTargetDogleg() const;
|
||||||
|
//! \red{This method purpose has not been reviewed yet}.
|
||||||
|
|
||||||
|
//! \function bool TrackElement::canRipple() const;
|
||||||
|
//! \red{This method purpose has not been reviewed yet}.
|
||||||
|
|
||||||
|
//! \function bool TrackElement::canDogleg();
|
||||||
|
//! \sa AutoSegment::canDogleg(). At Kite level, this variant of the method
|
||||||
|
//! will apply only on local segments and the segment must not already have
|
||||||
|
//! a source or target dogleg.
|
||||||
|
|
||||||
|
//! \function bool TrackElement::canDogleg( Interval );
|
||||||
|
//! \sa AutoSegment::canDogleg(). At Kite level, this variant of the method
|
||||||
|
//! will apply only on local segments and the segment must not already have
|
||||||
|
//! a source or target dogleg.
|
||||||
|
|
||||||
|
//! \function bool TrackElement::canDogleg( Katabatic::GCell* doglegGCell, unsigned int flags );
|
||||||
|
//! \sa AutoSegment::canDogleg(). At kite level, this variant of the method
|
||||||
|
//! is mainly targeted to global segment. For local segment it behave like
|
||||||
|
//! TrackElement::canDogleg(Interval). For global segment, make the break in
|
||||||
|
//! the requested GCell \c doglegGCell. If it's in the first or last GCell
|
||||||
|
//! and there is already a dogleg, allow to reuse it if \c flags contains
|
||||||
|
//! Kite::KtAllowDoglegReuse.
|
||||||
|
|
||||||
|
//! \function unsigned long TrackElement::getId() const;
|
||||||
|
//! \return The \c Id of the supporting AutoSegment, if there is any.
|
||||||
|
//! \e Zero otherwise.
|
||||||
|
|
||||||
|
//! \function unsigned int TrackElement::getDirection() const;
|
||||||
|
//! \return The direction of the supporting element (should match the
|
||||||
|
//! preferred direction of the Track).
|
||||||
|
|
||||||
|
//! \function Net* TrackElement::getNet() const;
|
||||||
|
//! \sreturn The Net associated to the element (may be \c NULL).
|
||||||
|
|
||||||
|
//! \function const Layer* TrackElement::getLayer() const;
|
||||||
|
//! \sreturn The Layer of the element (should match the one of the Track).
|
||||||
|
|
||||||
|
//! \function Track* TrackElement::getTrack() const;
|
||||||
|
//! \sreturn The Track into which the element is inserted (may be \c NULL).
|
||||||
|
|
||||||
|
//! \function size_t TrackElement::getIndex() const;
|
||||||
|
//! \sreturn The index of the element inside the Track's vector.
|
||||||
|
//!
|
||||||
|
//! \remark If the element is not inserted in a Track, it is set to
|
||||||
|
//! Track::npos, and obviously must not be used.
|
||||||
|
|
||||||
|
//! \function unsigned long TrackElement::getFreedomDegree() const;
|
||||||
|
//! \sreturn The degree of freedom of the element. It is used as a priority value
|
||||||
|
//! when sorting TrackElement (in RoutingEvent).
|
||||||
|
|
||||||
|
//! \function float TrackElement::getMaxUnderDensity ( unsigned int flags=0 ) const;
|
||||||
|
//! \sreturn The maximum density of all the GCells under this element.
|
||||||
|
|
||||||
|
//! \function Box TrackElement::getBoundingBox() const;
|
||||||
|
//! \sreturn The box that this element uses in the Track.
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::getPrevious() const;
|
||||||
|
//! \sreturn The previous TrackElement, on the same track and of a \e different net.
|
||||||
|
//! \sa Track::getPrevious().
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::getNext() const;
|
||||||
|
//! \sreturn The next TrackElement, on the same track and of a \e different net.
|
||||||
|
//! \sa Track::getNext().
|
||||||
|
|
||||||
|
//! \function DbU::Unit TrackElement::getAxis() const;
|
||||||
|
//! \sreturn The axis position of the element (must be the same as the Track).
|
||||||
|
|
||||||
|
//! \function DbU::Unit TrackElement::getSourceU() const;
|
||||||
|
//! \sreturn The minimun of the interval used by the element (cached in an
|
||||||
|
//! attribute).
|
||||||
|
|
||||||
|
//! \function DbU::Unit TrackElement::getTargetU() const;
|
||||||
|
//! \sreturn The maximum of the interval used by the element (cached in an
|
||||||
|
//! attribute).
|
||||||
|
|
||||||
|
//! \function DbU::Unit TrackElement::getLength() const;
|
||||||
|
//! \sreturn The length of the interval used by the element.
|
||||||
|
|
||||||
|
//! \function Interval TrackElement::getCanonicalInterval() const;
|
||||||
|
//! \sreturn The interval span used by the element inside the Track.
|
||||||
|
|
||||||
|
//! \function Interval TrackElement::getFreeInterval() const;
|
||||||
|
//! \sreturn The greatest free interval enclosing this element.
|
||||||
|
|
||||||
|
//! \function Interval TrackElement::getSourceConstraints() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::getSourceConstraints().
|
||||||
|
|
||||||
|
//! \function Interval TrackElement::getTargetConstraints() const;
|
||||||
|
//! \sa Katabatic::AutoSegment::getTargetConstraints().
|
||||||
|
|
||||||
|
//! \function DataNegociate* TrackElement::getDataNegociate ( unsigned int flags=KtDataSelf ) const;
|
||||||
|
//! \sreturn The additional data-structure supplied by the routing algorithm.
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::getCanonical ( Interval& i );
|
||||||
|
//! \red{Inner working still unclear to myself.}
|
||||||
|
|
||||||
|
//! \function size_t TrackElement::getGCells ( Katabatic::GCellVector& gcells ) const;
|
||||||
|
//! \sreturn The table of Katabatic::GCell underneath the element whole span.
|
||||||
|
|
||||||
|
//! \function unsigned int TrackElement::getDoglegLevel() const;
|
||||||
|
//! \sreturn The deepness of the dogleg.
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::getParent() const;
|
||||||
|
//! \sreturn The TrackElement from which the dogleg has been created, if any.
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::getSourceDogleg ();
|
||||||
|
//! \sreturn The source part of the segment from which the dogleg has been created.
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::getTargetDogleg ();
|
||||||
|
//! \sreturn The target part of the segment from which the dogleg has been created.
|
||||||
|
|
||||||
|
//! \function TrackElements TrackElement::getPerpandiculars ();
|
||||||
|
//! \sreturn The collection of all element perpandiculars to this one.
|
||||||
|
|
||||||
|
//! \function void TrackElement::setFlags ( unsigned int flags );
|
||||||
|
//! Set to \true \c flags in the element state array.
|
||||||
|
|
||||||
|
//! \function void TrackElement::unsetFlags ( unsigned int flags );
|
||||||
|
//! Reset to \false \c flags in the element state array.
|
||||||
|
|
||||||
|
//! \function void TrackElement::setTrack ( Track* track );
|
||||||
|
//! Insert the element into \c track, also used as an insertion marker.
|
||||||
|
|
||||||
|
//! \function void TrackElement::setIndex ( size_t index );
|
||||||
|
//! Cache the element's index in the Track internal vector.
|
||||||
|
|
||||||
|
//! \function void TrackElement::updateFreedomDegree ();
|
||||||
|
//! Update, from the element characteristics, it's degree of freedom.
|
||||||
|
|
||||||
|
//! \function void TrackElement::setDoglegLevel ( unsigned int level );
|
||||||
|
//! Sets the level of dogleg of the element.
|
||||||
|
|
||||||
|
//! \function void TrackElement::swapTrack ( TrackElement* other );
|
||||||
|
//! Swap the tracks of \c this and \c other.
|
||||||
|
|
||||||
|
//! \function void TrackElement::reschedule ( unsigned int level );
|
||||||
|
//! If the TrackElement has already an event scheduled, change the
|
||||||
|
//! level of this event, otherwise create a new event.
|
||||||
|
//!
|
||||||
|
//! \sa NegotiateWindow::rescheduleEvent().
|
||||||
|
|
||||||
|
//! \function void TrackElement::detach ();
|
||||||
|
//! Remove the link from the TrackElement to it's owning Track, marking
|
||||||
|
//! it for removal. The removal from the Track's vector is managed by
|
||||||
|
//! the Track itself during the Session revalidation stage.
|
||||||
|
|
||||||
|
//! \function void TrackElement::revalidate ();
|
||||||
|
//! Actualize the TrackElement characteristics from the supporting
|
||||||
|
//! elements (set of AutoSegment).
|
||||||
|
//!
|
||||||
|
//! \red{Must be completed with the event management}
|
||||||
|
|
||||||
|
//! \function void TrackElement::invalidate ();
|
||||||
|
//! \sa AutoSegment::invalidate().
|
||||||
|
|
||||||
|
//! \function void TrackElement::incOverlapCost ( Net* net, TrackCost& cost ) const;
|
||||||
|
//! \sa Compute the cost of overlap between this segment and the interval
|
||||||
|
//! specified in \c cost. Mainly calls the relevant callback.
|
||||||
|
|
||||||
|
// \function void TrackElement::dataInvalidate ();
|
||||||
|
// Invalidate the algorithm datas.
|
||||||
|
|
||||||
|
// \function void TrackElement::eventInvalidate ();
|
||||||
|
// Invalidate the associated RoutingEvent (if any).
|
||||||
|
|
||||||
|
//! \function void TrackElement::setAxis ( DbU::Unit, unsigned int flags=Katabatic::SegAxisSet );
|
||||||
|
//! Sets the axis of the TrackElement.
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::makeDogleg ();
|
||||||
|
//! Create a dogleg on the source end of the TrackSegment. Put the dogleg
|
||||||
|
//! axis on the source \redB{To be further reviewed}.
|
||||||
|
//!
|
||||||
|
//! \sa \ref secDogleg "Dogleg management".
|
||||||
|
//!
|
||||||
|
//! Post-processing done by TrackSegment::_postDoglegs().
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::makeDogleg ( Katabatic::GCell* gcell );
|
||||||
|
//! \sa AutoSegment::makeDogleg(), \ref secDogleg "Dogleg management".
|
||||||
|
//!
|
||||||
|
//! Post-processing done by TrackSegment::_postDoglegs().
|
||||||
|
|
||||||
|
//! \function TrackElement* TrackElement::makeDogleg ( Interval interval, unsigned int& flags );
|
||||||
|
//! \sa AutoSegment::makeDogleg(), \ref secDogleg "Dogleg management", the return flags
|
||||||
|
//! from this method are returned through the \c flags variable.
|
||||||
|
//!
|
||||||
|
//! Post-processing done by TrackSegment::_postDoglegs().
|
||||||
|
|
||||||
|
//! \function bool TrackElement::_check () const;
|
||||||
|
//! Check the coherency of the element. For a TrackSegment:
|
||||||
|
//! - The supporting AutoSegment the canonical one of the set.
|
||||||
|
//! - The cached \c min & \c max values are identical to the computed
|
||||||
|
//! ones.
|
||||||
|
//!
|
||||||
|
//! \sreturn \true on success.
|
||||||
|
|
||||||
|
//! \function SegmentOverlapCostCB* TrackElement::setOverlapCostCB ( SegmentOverlapCostCB* cb );
|
||||||
|
//! \param cb the new overlap cost callback.
|
||||||
|
//! \return the previous overlap cost callback.
|
||||||
|
//!
|
||||||
|
//! sets the overlap callback.
|
||||||
|
|
||||||
|
/*! \class SegmentObserver
|
||||||
|
*
|
||||||
|
* \brief Observer on the base AutoSegment
|
||||||
|
*
|
||||||
|
* The observer that will be hooked into the observable in the associated
|
||||||
|
* canonical AutoSegment. Used to propagate the invalidation/revalidation
|
||||||
|
* events from AutoSegment toward TrackSegment.
|
||||||
|
*
|
||||||
|
* As a secondary function, it is used by the Session::lookup() method
|
||||||
|
* to quicly retrieve TrackSegment from Katabatic::AutoSegment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function void SegmentObserver::notify ( unsigned int flags );
|
||||||
|
//! Implement the asymmetric invalidate/revalidate policy described in
|
||||||
|
//! Kite::Session. The invalidate is immediatly passed on while the
|
||||||
|
//! revalidate is ignored.
|
||||||
|
|
||||||
|
}
|
|
@ -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.
|
||||||
|
|
||||||
|
}
|
|
@ -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.
|
||||||
|
|
||||||
|
}
|
|
@ -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).
|
||||||
|
|
||||||
|
}
|
|
@ -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'.
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!-- -*- explicit-buffer-name: "customHierarchy.html<kite/doc>" -*- -->
|
||||||
|
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
|
||||||
|
<!-- $Id: customHierarchy.html,v 1.1 2007/09/15 13:10:12 jpc Exp $ -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||||
|
<title>Kite Documentation</title>
|
||||||
|
<link href="SoC.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<h1 id="pagetop" class="header">Kite Documentation</h1>
|
||||||
|
<center class="header">
|
||||||
|
<table class="header">
|
||||||
|
<tr><td><a href="customSummary.html">Summary</a>
|
||||||
|
<td><a href="namespaces.html">Namespaces</a>
|
||||||
|
<td><a href="customHierarchy.html">Class Hierarchy</a>
|
||||||
|
<td><a href="annotated.html">Classes</a>
|
||||||
|
<td><a href="functions.html">Member Index</a>
|
||||||
|
<!-- <td><a href="classes.html">Index2</a> -->
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
<br>
|
||||||
|
<hr>
|
||||||
|
<body>
|
||||||
|
<h1>Kite Synthetic Class Hierarchy</h1>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<p><b>The complete class hierarchy could be accessed <a href="hierarchy.html">here</a>.</b></p>
|
||||||
|
<p>All the classes below are in the <a href="namespaceKite.html">Kite</a> namespace.</p>
|
||||||
|
<p>The inheritance tree has been splitted/simplificated.</p>
|
||||||
|
<b>Legend :</b><br>
|
||||||
|
<pre class="fragment">
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="70"><td class="virtual"><a href="#pagetop">ClassA</a><td><b> <tt>ClassA</tt> is abstract</b></tr>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="#pagetop">ClassB</a><td><b> <tt>ClassB</tt> is instanciable</b></tr>
|
||||||
|
</table>
|
||||||
|
</pre>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<h2 class="classHierarchy">Tracks</h2>
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1TrackMarker.html">TrackMarker</a>
|
||||||
|
<tr><td width="70"><td class="virtual"><a href="classKite_1_1TrackElement.html">TrackElement</a>
|
||||||
|
</table>
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="140"><td class="normal"><a href="classKite_1_1SegmentObserver.html">SegmentObserver</a>
|
||||||
|
<tr><td width="140"><td class="normal"><a href="classKite_1_1TrackSegment.html">TrackSegment</a>
|
||||||
|
<tr><td width="140"><td class="normal"><a href="classKite_1_1TrackFixedSegment.html">TrackFixedSegment</a>
|
||||||
|
</table>
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="70"><td class="virtual"><a href="classKite_1_1Track.html">Track</a>
|
||||||
|
</table>
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="140"><td class="normal"><a href="classKite_1_1HorizontalTrack.html">HorizontalTrack</a>
|
||||||
|
<tr><td width="140"><td class="normal"><a href="classKite_1_1VerticalTrack.html">VerticalTrack</a>
|
||||||
|
</table>
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingPlane.html">RoutingPlane</a>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2 class="classHierarchy">Algorithm</h2>
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1DataNegociate.html">DataNegociate</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEvent_1_1Key.html">RoutingEvent::Key</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEvent.html">RoutingEvent</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEventQueue.html">RoutingEventQueue</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEventLoop.html">RoutingEventLoop</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1RoutingEventHistory.html">RoutingEventHistory</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1Session.html">Session</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1NegociateWindow.html">NegociateWindow</a>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
Transient Data Structures For RoutingEvent
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1SegmentAction.html">SegmentAction</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1Manipulator.html">Manipulator</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1SegmentFsm.html">SegmentFsm</a>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2 class="classHierarchy">Kite Engine</h2>
|
||||||
|
<table class="classHierarchy">
|
||||||
|
<tr><td width="70"><td class="normal"><a href="namespaceKite.html">Kite</a>
|
||||||
|
<tr><td width="70"><td class="normal"><a href="classKite_1_1KiteEngine.html">KiteEngine</a>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<table class="footer1">
|
||||||
|
<tr><td class="LFooter"><small>Customized Class Hierarchy</small>
|
||||||
|
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a>
|
||||||
|
</table>
|
||||||
|
<table class="footer2">
|
||||||
|
<tr><td class="LFooter">Kite Documentation
|
||||||
|
<td class="RFooter"><small>Copyright © 2008-2013 UPMC. All rights reserved</small>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,86 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
|
||||||
|
<!-- $Id: customSummary.html,v 1.1 2007/09/15 13:10:13 jpc Exp $ -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||||
|
<title>Kite Documentation</title>
|
||||||
|
<link href="SoC.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<h1 class="header">Kite Documentation</h1>
|
||||||
|
<center class="header">
|
||||||
|
<table class="header">
|
||||||
|
<tr>
|
||||||
|
<td><a href="customSummary.html">Summary</a></td>
|
||||||
|
<td><a href="namespaces.html">Namespaces</a></td>
|
||||||
|
<td><a href="customHierarchy.html">Class Hierarchy</a></td>
|
||||||
|
<td><a href="annotated.html">Classes</a></td>
|
||||||
|
<td><a href="functions.html">Member Index</a></td>
|
||||||
|
<!-- <td><a href="classes.html">Index2</a></td> -->
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
<br>
|
||||||
|
<hr>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>Kite Documentation Summary</h1>
|
||||||
|
<br>
|
||||||
|
<p><b>The classical Doxygen module documentation could be accessed <a href="modules.html">here</a>.</b></p>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<h2>Katabatic Concepts (internal)</h2>
|
||||||
|
<ol>
|
||||||
|
<li><a class="el" href="group__buildRules.html">Rules for building wires.</a>
|
||||||
|
<br>Rules for building AutoContacts. Global/Locals AutoSegments.
|
||||||
|
<li><a class="el" href="group__loadGlobalRouting.html">Global Routing Loading.</a>
|
||||||
|
<br>How the Knik global routing is loaded into Katabatic data-base.
|
||||||
|
Details the wiring topologies used to complete the routing to the
|
||||||
|
terminals.
|
||||||
|
<li><a class="el" href="group__collapseCanonical.html">AutoSegment Collapse & Canonical.</a>
|
||||||
|
<br>How to force alignment of AutoSegments.
|
||||||
|
<li><a class="el" href="group__layerAssign.html">Layer Assignment.</a>
|
||||||
|
<br>Simple strategy to put long wires on higher routing metals.
|
||||||
|
<li><a class="el" href="group__NetConstraints.html">Constraints Computations.</a>
|
||||||
|
<br>Compute the legal range of variation of each wire (note that the
|
||||||
|
constraints are stored on AutoContacts).
|
||||||
|
<li><a class="el" href="group__NetOptimals.html">AutoSegment Optimal Placement.</a>
|
||||||
|
<br>Compute the optimal range of variation of each wire.
|
||||||
|
<li><a class="el" href="group__katabaticSession.html">Katabatic Update Session Mechanism.</a>
|
||||||
|
<br>The Session mechanism for modifying the Katabatic data-base.
|
||||||
|
</ol>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<h2>API documentations</h2>
|
||||||
|
<ul>
|
||||||
|
<li><b><a href="customHierarchy.html">Synthetic Class Hierarchy.</a></b>
|
||||||
|
<li><b><a href="hierarchy.html">Complete Class Hierarchy (doxygen).</a></b>
|
||||||
|
<li><b><a href="annotated.html">Class List (doxygen).</a></b>
|
||||||
|
<li><b><a href="classes.html">Class Index (doxygen).</a></b>
|
||||||
|
<li><b><a href="modules.html">Modules (raw concepts).</a></b>
|
||||||
|
<li><b><a href="functions.html">Member Functions Index (doxygen).</a></b>
|
||||||
|
<li><b><a href="namespaces.html">Namespaces (doxygen).</a></b>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<h2>Developer's Notes</h2>
|
||||||
|
<ul>
|
||||||
|
<li><b><a href="pageNotes.html">Notes to myself.</a></b>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<table class="footer1">
|
||||||
|
<tr>
|
||||||
|
<td class="LFooter"><small>Customized Concepts (a.k.a. modules)</small></td>
|
||||||
|
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<table class="footer2">
|
||||||
|
<tr>
|
||||||
|
<td class="LFooter">Kite Documentation</td>
|
||||||
|
<td class="RFooter"><small>Copyright © 2005-2013 LIP6. All rights reserved</small></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,196 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Kite {
|
||||||
|
|
||||||
|
/*! \page pageNotes Notes
|
||||||
|
*
|
||||||
|
* \section Summary
|
||||||
|
*
|
||||||
|
* - \ref ssecVariousNotes "Various Things to Remeber"
|
||||||
|
* - \ref secPendingModifications "Pending Modifications"
|
||||||
|
* - \ref secModificationsHistory "Modifications History"
|
||||||
|
* - \ref ssecArchitectureChanges "Changes in the general architecture"
|
||||||
|
* - \ref ssecModificationsKiteEngine "Changes in KiteEngine class design"
|
||||||
|
* - \ref ssecModificationsDataNegociate "Changes in DataNegociate class design"
|
||||||
|
* - \ref ssecModificationsTrackElement "Changes in TrackElement class design"
|
||||||
|
* - \ref ssecModificationsTrackSegment "Changes in TrackSegment class design"
|
||||||
|
* - \ref ssecModificationsAutoSegment "Changes in AutoSegment class design"
|
||||||
|
* - \ref ssecModificationsAutoContact "Changes in AutoContact class design"
|
||||||
|
* - \ref ssecBugBusting "Bug Solving Memento"
|
||||||
|
* - \ref ssecNanoRoute "Evaluation with Cadence NanoRoute"
|
||||||
|
*
|
||||||
|
* \section ssecVariousNotes Various Things to Remember
|
||||||
|
*
|
||||||
|
* - <b>Determinism checking.</b> The trace level to get only determinism related
|
||||||
|
* log is \c 500. Each line for the determinism is prepended with 'Deter|',
|
||||||
|
* possible with some leading spaces.
|
||||||
|
*
|
||||||
|
* - The router only sees/manages the aligned segment sets (through a pseudo-
|
||||||
|
* decorator on their canonical segment). So the non-canonical segments
|
||||||
|
* and the contacts should not be handled at all at this level.
|
||||||
|
* - Do do confuse the Session::Event, events that modificate
|
||||||
|
* the state of the Kite database (insert, move or remove TrackSegment
|
||||||
|
* in Track) and the RoutingEvent class which request that a segment
|
||||||
|
* must be processed.
|
||||||
|
* - In the various processing method of RoutingEvent, when a TrackSegment
|
||||||
|
* can be inserted inside a Track a Session::Event is generated but
|
||||||
|
* no further RoutingEvent, this end the placement processus of
|
||||||
|
* segment (until it is ripped-up).
|
||||||
|
* - AutoSegment do not invalidate their S/T anchor contacts.
|
||||||
|
* - AutoContact invalidate their anchored upon AutoSegment.
|
||||||
|
* - Now that the Hurricane database is deterministic, the router
|
||||||
|
* seems to be likewise.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secPendingModifications Pending Modifications
|
||||||
|
*
|
||||||
|
* - In SegmentAction::doAction(), completly disable the movement of
|
||||||
|
* TrackSegment on it's target Track axis. This should not be
|
||||||
|
* needed as, if the algorithm as worked correctly, the next time
|
||||||
|
* it's RoutingEvent is processed, the target Track will have a
|
||||||
|
* free space to insert into. Then the Track insertion will
|
||||||
|
* set the TrackSegment axis.
|
||||||
|
* - Has to complete the lazy evaluation of the TrackSegment / DataNegociate
|
||||||
|
* / RoutingEvent. There is still some redundancy when the key of
|
||||||
|
* the RoutingEvent is updated.
|
||||||
|
* - In AutoContact::updateTopology() & AutoContact::updateGeometry()
|
||||||
|
* we could avoid to systematically run through the Hooks to cache
|
||||||
|
* the connected segments. This can be done once at the first call
|
||||||
|
* of either method (whichever comes first) on the first revalidate.
|
||||||
|
* Afterwards the cache can be updated only by AutoContact::updateTopology().
|
||||||
|
* - The canonization is done in two places, directly on a set of aligneds
|
||||||
|
* AutoSegments through AutoSegment::canonize() and for the whole net
|
||||||
|
* Session::_canonize(), which is called after the initial creation and
|
||||||
|
* each time the topology is modificated. The later may be suppressed
|
||||||
|
* if we uses more intelligently the former, and gain some more speedup.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section secModificationsHistory Modifications History
|
||||||
|
*
|
||||||
|
* \subsection ssecArchitectureChanges Changes in the general architecture
|
||||||
|
*
|
||||||
|
* - <b>Lazy Update.</b> Update of DataNegociate and RoutingEvent
|
||||||
|
* are now delayed until the event is processed, and systematically
|
||||||
|
* done at this point. Thus, the explicit invalidation of those
|
||||||
|
* objects is no longer needed. The revalidation is no longer
|
||||||
|
* triggered by the revalidation of TrackSegment.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \subsection ssecModificationsKiteEngine Changes in KiteEngine class design
|
||||||
|
*
|
||||||
|
* - Suppress the lookup table of Hurricane::Segment toward
|
||||||
|
* TrackSegment. Instead uses the Observer mecanism between
|
||||||
|
* Katabatic::AutoSegment and TrackSegment.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \subsection ssecModificationsDataNegociate Changes in DataNegociate class design
|
||||||
|
*
|
||||||
|
* - Merge in the separate class \c Cost.
|
||||||
|
* - Suppress the \c SlackState::Desalignate, due to the simplificated
|
||||||
|
* structure of the AutoSegment/AutoContacts (no more collapseds, or
|
||||||
|
* forced alignements).
|
||||||
|
* - Displace the computation and caching of the perpandiculars and
|
||||||
|
* perpandicular free interval from RoutingEvent into DataNegociate.
|
||||||
|
* Allows code factorization with the attractors computation, and
|
||||||
|
* data size reduction as there is exaclty one DataNegociate but
|
||||||
|
* there may be more than one RoutingEvent for the same TrackSegment.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \subsection ssecModificationsTrackElement Changes in TrackElement class design
|
||||||
|
*
|
||||||
|
* - Due to the simplificated structure of the Katabatic contacts
|
||||||
|
* (terminal, turn, vtee & htee), there's no longer collapsed
|
||||||
|
* AutoSegment or \e expandable contacts. The \b desalignate
|
||||||
|
* feature, relaxing constraints due to collapsed segments
|
||||||
|
* or contacts with more than three segments, is no longer
|
||||||
|
* implemented.
|
||||||
|
* \redB{Have to redevelop a method to break long segments linked}
|
||||||
|
* \redB{by HTee or VTee.}
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \subsection ssecModificationsTrackSegment Changes in TrackSegment class design
|
||||||
|
*
|
||||||
|
* - The method \c TrackSegment::_postModify() is merged with
|
||||||
|
* TrackSegment::_postDoglegs() as, in the context of TrackSegment
|
||||||
|
* the only used topological modifications goes through the creation
|
||||||
|
* of one or more dogleg.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \subsection ssecModificationsAutoSegment Changes in AutoSegment class design
|
||||||
|
*
|
||||||
|
* - In AutoSegment::_makeDogleg(), update the local/global status
|
||||||
|
* of the involved AutoSegment and re-canonize only what is necessary.
|
||||||
|
* Thus, guarantee that the net's topology is still valid after this
|
||||||
|
* method call and no topological update is needed at Session level
|
||||||
|
* (should be \e much faster).
|
||||||
|
* In this method, the code sharing between AutoHorizontal and
|
||||||
|
* AutoVertical can still be increased (update mechanisms are
|
||||||
|
* identicals).
|
||||||
|
* - The \c id support is now also implemented at Hurricane level.
|
||||||
|
* We may choose to use as a replacement of the one already present
|
||||||
|
* in AutoSegment. But in that case, we at least must cache the
|
||||||
|
* id in the AutoSegment. So we will not gain in memory footprint,
|
||||||
|
* the only benefit would be to have coherent id number throughout
|
||||||
|
* all the tools, but the sequentiality will be lost (this may not
|
||||||
|
* be a big issue).
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \subsection ssecModificationsAutoContact Changes in AutoContact class design
|
||||||
|
*
|
||||||
|
* - In AutoSegment::invalidate(), no longer uses collection to
|
||||||
|
* walk through attached AutoSegment, directly uses the cache.
|
||||||
|
* Much simple and efficient as we exactly know what is attached
|
||||||
|
* on every kind of contact.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section ssecBugBusting Bug Solving Memento
|
||||||
|
*
|
||||||
|
* <b>LUT lookup change:</b> When breaking a TrackSegment, the break may
|
||||||
|
* not occurs in the associated canonical AutoSegment. In that case the
|
||||||
|
* <code>dogleg[O]</code> will not match the one that is looked up
|
||||||
|
* for the broken (canonical) segment. Thus it was not a bug but a
|
||||||
|
* misunderstanding...
|
||||||
|
*
|
||||||
|
* <b>Overlap of perpandiculars after a dogleg creation:</b>
|
||||||
|
* The axis of the new parallel was not set to the axis of it's parent.
|
||||||
|
* This was due to the uses of AutoSegment::setAxis() in
|
||||||
|
* AutoHorizontal::_makeDogleg() which silently
|
||||||
|
* do nothing on non-canonical AutoSegment, and at this point, the
|
||||||
|
* re-canonisation did not yet take place. Now Uses AutoSegment::_setAxis()
|
||||||
|
* the atomic variant wich works inconditionnaly.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \section ssecNanoRoute Evaluation with Cadence NanoRoute
|
||||||
|
*
|
||||||
|
* To perform a comparison with NanoRoute the procedure is as follow:
|
||||||
|
*
|
||||||
|
* - Export the design in Alliance \c DEF format. It will generate both
|
||||||
|
* \c DEF file and the supporting \c LEF file containing the technology
|
||||||
|
* and the abstract of all the standard cell of the design.
|
||||||
|
* As Alliance uses symbolic units (lambda), they are translated with
|
||||||
|
* the simple rule: <b>1 lambda == 1 micron</b>.
|
||||||
|
*
|
||||||
|
* - Run the commands in NanoRoute:
|
||||||
|
* - <tt>loadLefFile design.lef</tt>
|
||||||
|
* - <tt>loadDefFile design.def</tt>
|
||||||
|
* - <tt>generateTracks</tt>
|
||||||
|
* - <tt>generateVias</tt>
|
||||||
|
* - <tt>setNanoRouteMode -quiet -drouteFixAntenna 0</tt>
|
||||||
|
* - <tt>setNanoRouteMode -quiet -drouteStartIteration default</tt>
|
||||||
|
* - <tt>setNanoRouteMode -quiet -routeTopRoutingLayer default</tt>
|
||||||
|
* - <tt>setNanoRouteMode -quiet -routeBottomRoutingLayer 2</tt>
|
||||||
|
* - <tt>setNanoRouteMode -quiet -drouteEndIteration default</tt>
|
||||||
|
* - <tt>setNanoRouteMode -quiet -routeWithTimingDriven false</tt>
|
||||||
|
* - <tt>setNanoRouteMode -quiet -routeWithSiDriven false</tt>
|
||||||
|
* - <tt>routeDesign -globalDetail</tt>
|
||||||
|
*
|
||||||
|
* - To perform as fair a comparison as possible, those commands disable
|
||||||
|
* antenna effect protection and disable the use of the \c M1 as a
|
||||||
|
* routing layer (<tt>-routeBottomRoutingLayer 2</tt>). Those commands
|
||||||
|
* are issued through the graphical interface of NanoRoute.
|
||||||
|
*
|
||||||
|
* <em>To see the resulting layout, do not forget to switch the view mode.</em>
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue