973 lines
50 KiB
C++
973 lines
50 KiB
C++
|
|
// -*- C++ -*-
|
|
|
|
namespace Katabatic {
|
|
|
|
/*! \class AutoSegment
|
|
*
|
|
* \brief Abstract base class for AutoSegment
|
|
*
|
|
*
|
|
* \section secASCreation Creating AutoHorizontal & AutoVertical
|
|
*
|
|
* AutoSegment is the abstract base class for AutoHorizontal and
|
|
* AutoVertical. They are must be created only through the
|
|
* factory method: AutoSegment::create().
|
|
*
|
|
*
|
|
* \section secASCharacteristics Characteristics of AutoSegments
|
|
*
|
|
* <ul>
|
|
* <li>Unique ID: to ease the enforcing of a deterministic behavior
|
|
* and to gain some independance from the pointers, each AutoSegment
|
|
* is associated with an unique identifier.
|
|
* \red{<b>IDs</b> are now directly taken from the Hurricane::Segment.}
|
|
* <li>Source contact is always lesser than Target contact
|
|
* <code>(Xs,Ys) < (Xt,Yt)</code>.
|
|
* <li>When assembled through AutoContactVTee or AutoContactHTee,
|
|
* AutoSegments became (i.e. must be kept) aligneds. Among a
|
|
* set of aligned AutoSegments, we distinguish a representative
|
|
* trough which we can manipulate the whole set. This representative
|
|
* is called the \e canonical AutoSegment and is the one with the
|
|
* lowest \c id).
|
|
* <li>When an aligned set contains at least one global, all the segments
|
|
* of the set are tagged Katabatic::SegWeakGlobal. This is
|
|
* especially useful on local ones to know if they are part of a
|
|
* much longer wire.
|
|
*
|
|
* Conversely, a set of aligned may contains only local segments and
|
|
* thus will not have the flag set.
|
|
* <li>To allow some optimization, the Katabatic::SegNotAligned
|
|
* tells if a segment is part of an aligned set. It is deduced from
|
|
* the type of both source and target contact: not on the parallel
|
|
* branch of a tee.
|
|
* </ul>
|
|
*
|
|
* <b>The Ever Fragmenting Data Structure</b>
|
|
*
|
|
* All the transformations applied to the database, after it's initial
|
|
* building, can be reduced to making new doglegs (and layer changes).
|
|
* Another way to put it, is that no Tee is ever created after the
|
|
* initial stage. The consequence is that the segments are only fragmenting
|
|
* more and more (up to a certain limit). The aligneds sets are progessively
|
|
* broken apart as needed, and until there remains only one tee per set
|
|
* (the two segments on the aligned branch).
|
|
*
|
|
*
|
|
* \section secASOperations Operations on AutoSegments
|
|
*
|
|
* <ul>
|
|
* <li><b>Slackening.</b> Constraints transmited through either source
|
|
* or target AutoContact are too tight (tighter than the GCell),
|
|
* by adding straps in the perpandicular direction, the full slack
|
|
* of the segment is restored.
|
|
* <li><b>Layer Change.</b> One or two layers above or below the
|
|
* current layer. One up/down may means into the perpandicular
|
|
* routing direction.
|
|
* <li><b>Dogleg Creation.</b> Mean breaking the segment in two.
|
|
* This operation is used to slacken the constraints on a segment
|
|
* or restore connexity on source/target contact after a layer
|
|
* change. The new segment is always created on the source.
|
|
* </ul>
|
|
*
|
|
*
|
|
* \section secASInvalidate Invalidate on AutoSegments
|
|
*
|
|
* The simple invalidation of an AutoSegment <b>do not</b> invalidate
|
|
* it's source & target contact.
|
|
*
|
|
* An axis position change or a layer change both invalidate the
|
|
* AutoSegment <b>and</b> it's source & target contacts.
|
|
*
|
|
* For the complete invalidation/revalidation mechanism see
|
|
* \ref secSessionAlgo "Session Algorithm".
|
|
*
|
|
*
|
|
* \section secASAttributes Main Attributes of AutoSegments
|
|
*
|
|
* AutoSegment retains all attributes from Segment. The Segment itself
|
|
* beeing accessible through the base() methods.
|
|
* <ul>
|
|
* <li>An unique \c Id (for determinism).
|
|
* <li>The GCell from wich it starts from. It is the GCell of the
|
|
* source AutoContact.
|
|
* <li>A state, combination of flags from Katabatic::AutoSegmentFlag.
|
|
* <li>An interval for the optimal range of the AutoSegment axis.
|
|
* <li>An interval for user's defined constraint on the axis.
|
|
* <li>The interval giving the complete length of the AutoSegment,
|
|
* that is, with all extentions cap taken into account.
|
|
* This interval is refered as the \e span.
|
|
* </ul>
|
|
*
|
|
*
|
|
* \section secASImplementation Implementation Details
|
|
*
|
|
* AutoSegment / AutoHorizontal & AutoVertical are kind of decorators of
|
|
* Hurricane::Segment (they do not scrictly respect the pattern).
|
|
*
|
|
* Canonical AutoSegment can should be considered as a kind of Composite.
|
|
*
|
|
* Thoses objects are created using a Factory method.
|
|
*
|
|
*
|
|
* \section secASMethodsClassif Methods Classification
|
|
*
|
|
* <ul>
|
|
* <li><em>Wrapper methods</em> on the underlying Hurricane::Segment.
|
|
* </ul>
|
|
* <ul>
|
|
* <li><em>Atomic methods</em> on AutoSegment, that is, which applies exactly
|
|
* on the current AutoSegment.
|
|
* </ul>
|
|
* <ul>
|
|
* <li><em>Canonical methods</em> that applies on the set of aligned AutoSegments.
|
|
* There are two kind of those, the methods part of the API, and
|
|
* the ones that make the link with the atomic methods. Those
|
|
* intermediate methods hide some cumbersome AutoSegment list
|
|
* parameters.
|
|
* <ul>
|
|
* <li>AutoSegment::invalidate()
|
|
* <li>AutoSegment::computeOptimal()
|
|
* <li>AutoSegment::setAxis()
|
|
* <li>AutoSegment::toConstraintAxis()
|
|
* <li>AutoSegment::toOptimalAxis()
|
|
* </ul>
|
|
* </ul>
|
|
* <ul>
|
|
* <li><em>Uniform access</em>, to simplify the managment of AutoHorizontal
|
|
* and AutoVertical through AutoSegment, a set of uniformized methods is
|
|
* introduced. For instance, to avoid to check the dynamic type to choose
|
|
* to call getSourceX() or getSourceY(), we may call getSourceU().
|
|
* Uniform methods are named by replacing \c X/Y with \c U.
|
|
* <ul>
|
|
* <li>AutoSegment::getSourceU()
|
|
* <li>AutoSegment::getTargetU()
|
|
* <li>AutoSegment::getDuSource()
|
|
* <li>AutoSegment::getDuTarget()
|
|
* <li>AutoSegment::getSpanU()
|
|
* <li>AutoSegment::setDuSource()
|
|
* <li>AutoSegment::setDuTarget()
|
|
* </ul>
|
|
* </ul>
|
|
*/
|
|
|
|
|
|
//! \enum AutoSegmentFlag
|
|
//! Set of flags to describe the internal state of an AutoSegment.
|
|
|
|
//! \var AutoSegmentFlag::SegHorizontal
|
|
//! This AutoSegment is associated to a Hurricane::Horizontal, if not
|
|
//! set, it is associated to a Hurricane::Vertical. Set when the object
|
|
//! is constructed.
|
|
|
|
//! \var AutoSegmentFlag::SegFixed
|
|
//! The Hurricane::Segment associated must/cannot be moved.
|
|
|
|
//! \var AutoSegmentFlag::SegGlobal
|
|
//! The AutoSegment span between at least two GCells (i.e. not fully enclosed
|
|
//! in one).
|
|
|
|
//! \var AutoSegmentFlag::SegWeakGlobal
|
|
//! The AutoSegment is part of an aligned set which contains at least a global.
|
|
//! The global segment is itself tagged as weak global.
|
|
|
|
//! \var AutoSegmentFlag::SegCanonical
|
|
//! This AutoSegment is the designated representant of a set of aligned
|
|
//! AutoSegment.
|
|
|
|
//! \var AutoSegmentFlag::SegBipoint
|
|
//! This AutoSegment is a straight wire between two terminal AutoContact.
|
|
|
|
//! \var AutoSegmentFlag::SegDogleg
|
|
//! This AutoSegment has been created as the perpandicular part of a dogleg.
|
|
|
|
//! \var AutoSegmentFlag::SegStrap
|
|
//! This AutoSegment has been created to to reconnect parts of an AutoSegment
|
|
//! after slackening.
|
|
|
|
//! \var AutoSegmentFlag::SegSourceTop
|
|
//! The source contact of this segment is connected to the <em>top</em> layer.
|
|
|
|
//! \var AutoSegmentFlag::SegSourceBottom
|
|
//! The source contact of this segment is connected to the <em>bottom</em> layer.
|
|
|
|
//! \var AutoSegmentFlag::SegTargetTop
|
|
//! The target contact of this segment is connected to the <em>top</em> layer.
|
|
|
|
//! \var AutoSegmentFlag::SegTargetBottom
|
|
//! The target contact of this segment is connected to the <em>bottom</em> layer.
|
|
|
|
//! \var AutoSegmentFlag::SegLayerChange
|
|
//! This AutoSegment has been created to to reconnect parts of an AutoSegment
|
|
//! after a layer change.
|
|
|
|
//! \var AutoSegmentFlag::SegSlackened
|
|
//! This AutoSegment has been slackened, that is freed from any constraints from
|
|
//! source or target through the insertion of straps.
|
|
|
|
//! \var AutoSegmentFlag::SegStrongTerminal
|
|
//! This AutoSegment directly connected to a terminal.
|
|
|
|
//! \var AutoSegmentFlag::SegWeakTerminal1
|
|
//! This AutoSegment indirectly connected to a terminal with medium strength.
|
|
|
|
//! \var AutoSegmentFlag::SegWeakTerminal2
|
|
//! This AutoSegment indirectly connected to a terminal with weak strength.
|
|
|
|
//! \var AutoSegmentFlag::SegNotSourceAligned
|
|
//! This source contact of the segment is not the aligned part of a tee
|
|
//! (\c h1 or \c h2 for a \c HTee, \c v1 or \c v2 for a \c VTee).
|
|
//!
|
|
//! \sa AutoSegmentFlag::SegNotAligned
|
|
|
|
//! \var AutoSegmentFlag::SegNotTargetAligned
|
|
//! This target contact of the segment is not the aligned part of a tee
|
|
//! (\c h1 or \c h2 for a \c HTee, \c v1 or \c v2 for a \c VTee).
|
|
//!
|
|
//! \sa AutoSegmentFlag::SegNotAligned
|
|
|
|
//! \var AutoSegmentFlag::SegAxisSet
|
|
//! This AutoSegment has been explicitly positionned at least once.
|
|
|
|
//! \var AutoSegmentFlag::SegInvalidated
|
|
//! This position or topology of this AutoSegment has been changed, needing
|
|
//! a revalidation.
|
|
|
|
//! \var AutoSegmentFlag::SegInvalidatedLayer
|
|
//! The segment has been chenged of layer, but the source & target AutoContact
|
|
//! have not been topologicaly checked yet. This flag \b must be used in
|
|
//! whith AutoSegmentFlag::SegInvalidated.
|
|
|
|
//! \var AutoSegmentFlag::SegCreated
|
|
//! The AutoSegment has just been created. This flag is set only from the
|
|
//! contruction of the object until is \e first revalidation. Used to
|
|
//! disable some tests that cannot be satisfied initially.
|
|
|
|
//! \var AutoSegmentFlag::SegWeakTerminal
|
|
//! A mask composed of:
|
|
//! - Katabatic::SegStrongTerminal
|
|
//! - Katabatic::SegWeakTerminal1
|
|
//! - Katabatic::SegWeakTerminal2
|
|
|
|
//! \var AutoSegmentFlag::SegNotAligned
|
|
//! A mask composed of:
|
|
//! - Katabatic::SegNotSourceAligned
|
|
//! - Katabatic::SegNotTargetAligned
|
|
//!
|
|
//! This mask is a quick way to know if a segment is \b not part of an aligned set.
|
|
//! It means that the segment is, on both ends, either connected to a terminal,
|
|
//! a turn <em>or the stem part of a tee</em>.
|
|
|
|
|
|
//! \function AutoSegment* AutoSegment::create ( AutoContact* source, AutoContact* target, Segment* hurricaneSegment );
|
|
//! \param source The source AutoContact.
|
|
//! \param target The target AutoContact.
|
|
//! \param hurricaneSegment The Hurricane::Segment to decorate.
|
|
//! \return The AutoHorizontal/AutoVertical decorator segment.
|
|
//!
|
|
//! Factory method to create AutoHorizontal or AutoVertical. It is important
|
|
//! to note that this function may modify the underlying Hurricane::Segment.
|
|
//! - Layer is set to the default (bottom) routing Layers.
|
|
//! - Source & target anchor of \c hurricaneSegment are set on \c source
|
|
//! and \c target. If the \c hurricaneSegment is already anchored and
|
|
//! \c source or \c target are not the one decorating the anchors, an
|
|
//! exception is thrown.
|
|
|
|
//! \function AutoSegment* AutoSegment::create ( AutoContact* source, AutoContact* target, unsigned int flags );
|
|
//! \param source The source AutoContact.
|
|
//! \param target The target AutoContact.
|
|
//! \param flags Specify the constructor behavior.
|
|
//! \return The AutoHorizontal/AutoVertical.
|
|
//!
|
|
//! Factory method to create AutoHorizontal or AutoVertical.
|
|
//! \c flags indicate the direction (KbHorizontal or KbVertical).
|
|
//! The underlying Hurricane segment is also created.
|
|
|
|
//! \function Segment* AutoSegment::base() const;
|
|
//! \sreturn the decorated Hurricane::Segment (const flavor).
|
|
|
|
//! \function Segment* AutoSegment::base();
|
|
//! \sreturn the decorated Hurricane::Segment.
|
|
|
|
//! \function Horizontal* AutoSegment::getHorizontal();
|
|
//! \sreturn If the decorated segment is a Hurricane::Horizontal, return it.
|
|
//! \c NULL otherwise.
|
|
|
|
//! \function Vertical* AutoSegment::getVertical();
|
|
//! \sreturn If the decorated segment is a Hurricane::Vertical, return it.
|
|
//! \c NULL otherwise.
|
|
|
|
//! \function Cell* AutoSegment::getCell() const;
|
|
//! \see Segment::getCell().
|
|
|
|
//! \function Net* AutoSegment::getNet() const;
|
|
//! \see Segment::getNet().
|
|
|
|
//! \function const Layer* AutoSegment::getLayer() const;
|
|
//! \see Segment::getLayer().
|
|
|
|
//! \function BoundingBox* AutoSegment::getBoundingBox() const;
|
|
//! \see Segment::getBoundingBox().
|
|
|
|
//! \function Hook* AutoSegment::getSourceHook();
|
|
//! \see Segment::getSourceHook().
|
|
|
|
//! \function Hook* AutoSegment::getTargetHook();
|
|
//! \see Segment::getTargetHook().
|
|
|
|
//! \function Contact* AutoSegment::getSource() const;
|
|
//! \see Segment::getSource().
|
|
|
|
//! \function Contact* AutoSegment::getTarget() const;
|
|
//! \see Segment::getTarget().
|
|
|
|
//! \function Component* AutoSegment::getOppositeAnchor( Component* ) const;
|
|
//! \see Segment::getNet().
|
|
|
|
//! \function Components AutoSegment::getAnchors() const;
|
|
//! \see Segment::getAnchors().
|
|
|
|
//! \function DbU::Unit AutoSegment::getX() const;
|
|
//! \see Segment::getX().
|
|
|
|
//! \function DbU::Unit AutoSegment::getY() const;
|
|
//! \see Segment::getY().
|
|
|
|
//! \function DbU::Unit AutoSegment::getWidth() const;
|
|
//! \see Segment::getWidth().
|
|
|
|
//! \function DbU::Unit AutoSegment::getLength() const;
|
|
//! \see Segment::getLength().
|
|
|
|
//! \function DbU::Unit AutoSegment::getSourcePosition() const;
|
|
//! \see Segment::getSourcePosition().
|
|
|
|
//! \function DbU::Unit AutoSegment::getTargetPosition() const;
|
|
//! \see Segment::getTargetPosition().
|
|
|
|
//! \function DbU::Unit AutoSegment::getSourceX() const;
|
|
//! \see Segment::getSourceX().
|
|
|
|
//! \function DbU::Unit AutoSegment::getSourceY() const;
|
|
//! \see Segment::getSourceY().
|
|
|
|
//! \function DbU::Unit AutoSegment::getTargetX() const;
|
|
//! \see Segment::getTargetX().
|
|
|
|
//! \function DbU::Unit AutoSegment::getTargetY() const;
|
|
//! \see Segment::getTargetY().
|
|
|
|
//! \function DbU::Unit AutoSegment::invert();
|
|
//! \see Segment::invert().
|
|
|
|
//! \function void AutoSegment::setLayer( const Layer* );
|
|
//! \see Segment::setLayer().
|
|
|
|
//! \function bool AutoSegment::isHorizontal() const;
|
|
//! \sreturn \true if the Hurricane::Segment is Horizontal.
|
|
|
|
//! \function bool AutoSegment::isVertical() const;
|
|
//! \sreturn \true if the Hurricane::Segment is Vertical.
|
|
|
|
//! \function bool AutoSegment::isGlobal() const;
|
|
//! \sreturn \true if the segment is global (span over more than one GCell).
|
|
|
|
//! \function bool AutoSegment::isLocal() const;
|
|
//! \sreturn \true if the segment is local (fully enclosed in one GCell).
|
|
|
|
//! \function bool AutoSegment::isFixed() const;
|
|
//! \sreturn \true if segment must not be moved by the router.
|
|
|
|
//! \function bool AutoSegment::isBipoint() const;
|
|
//! \sreturn \true if the segment straigh join two terminals.
|
|
|
|
//! \function bool AutoSegment::isWeakTerminal() const;
|
|
//! \sreturn \true if segment is indirectly connected to a terminal.
|
|
|
|
//! \function bool AutoSegment::isStrongTerminal( unsigned int flags=0 ) const;
|
|
//! \sreturn \true if segment is directly connected to a terminal.
|
|
|
|
//! \function bool AutoSegment::isLayerChange() const;
|
|
//! \sreturn \true if segment is a strap used only to connect between two different
|
|
//! metal layers on the way up or down.
|
|
|
|
//! \function bool AutoSegment::isStrap() const;
|
|
//! \sreturn \true if segment has been created from a slackening operation to
|
|
//! restore the slack of another segment.
|
|
|
|
//! \function bool AutoSegment::isDogleg() const;
|
|
//! \sreturn \true if segment has been created as the perpandicular part of a dogleg.
|
|
|
|
//! \function bool AutoSegment::isInvalidated() const;
|
|
//! \sreturn \true if segment has been moved or topologicaly altered.
|
|
|
|
//! \function bool AutoSegment::isInvalidatedLayer() const;
|
|
//! \sreturn \true if segment has been changed of layer. Source and Target AutoContact
|
|
//! may need to be altered.
|
|
|
|
//! \function bool AutoSegment::isCreated() const;
|
|
//! \sreturn \true if segment has just been created and is not revalidated for the
|
|
//! first time
|
|
|
|
//! \function bool AutoSegment::isCanonical() const;
|
|
//! \sreturn \true if segment is the representant of an aligned set.
|
|
|
|
//! \function bool AutoSegment::isUnsetAxis() const;
|
|
//! \sreturn \true if the segment axis has never been set.
|
|
|
|
//! \function bool AutoSegment::isSlackened() const;
|
|
//! \sreturn \true if the segment has already been slackened.
|
|
|
|
//! \function unsigned int AutoSegment::canDogleg( Interval interval );
|
|
//! \sreturn non-zero if the aligned set of segment can be broken \e outside \c interval.
|
|
//! The returned value could be zero (failure) or Katabatic::KbDoglegOnLeft
|
|
//! or Katabatic::KbDoglegOnRight menaing that the aligned set could be broken
|
|
//! on the left of the \c interval (resp. right of it).
|
|
|
|
// \function bool AutoSegment::canDesalignate( AutoContact* contact ) const;
|
|
// \sreturn \true if \c contact restrict the slack of the segment.
|
|
|
|
//! \function bool AutoSegment::canSlacken( unsigned int flags=0 ) const;
|
|
//! \sreturn \true if the segment can be slackened. That is, source or target constraints
|
|
//! are less than three pitches.
|
|
//!
|
|
//! If \c flags contains KbPropagate, look on the whole aligned set.
|
|
|
|
//! \function bool AutoSegment::_canSlacken() const;
|
|
//! \sreturn \true if the segment can be slackened. That is, source or target constraints
|
|
//! are less than three pitches.
|
|
|
|
//! \function bool AutoSegment::canMoveULeft( float reserve ) const;
|
|
//! \return \true if the \e global segment can be moved on the left GCell (for a
|
|
//! vertical) or down (for an horizontal). The move is accepted only if
|
|
//! it do not change the amount of global wiring. Thus the following
|
|
//! conditions:
|
|
//! - The segment mustn't be on the leftmost GCell (obvious...).
|
|
//! - The segment must be global.
|
|
//! - The source and target contacts must be AutoContactTurn(s).
|
|
//! - At least one of the perpandicular must be global \b and connected
|
|
//! through the \e target. That is, it's a global which extends toward
|
|
//! left.
|
|
//! - The GCell of maximum density on the left must remains below the
|
|
//! current GCell of maximum density, with a margin of \c reserve
|
|
//! (expressed in total saturation percentage).
|
|
|
|
//! \function bool AutoSegment::canMoveURight( float reserve ) const;
|
|
//! \return \true if the \e global segment can be moved on the right GCell (for a
|
|
//! vertical) or up (for an horizontal). The move is accepted only if
|
|
//! it do not change the amount of global wiring. Thus the following
|
|
//! conditions:
|
|
//! - The segment mustn't be on the leftmost GCell (obvious...).
|
|
//! - The segment must be global.
|
|
//! - The source and target contacts must be AutoContactTurn(s).
|
|
//! - At least one of the perpandicular must be global \b and connected
|
|
//! through the \e source. That is, it's a global which extends toward
|
|
//! right.
|
|
//! - The GCell of maximum density on the left must remains below the
|
|
//! current GCell of maximum density, with a margin of \c reserve
|
|
//! (expressed in total saturation percentage).
|
|
|
|
//! \function bool AutoSegment::canMoveUp( float reserve, unsigned int flags ) const;
|
|
//! \param reserve Number of track that must remains free \e after the move.
|
|
//! \param flags Modificate the method behavior, see below.
|
|
//! \return \true if the segment can be moved up, that is to the next layer above in
|
|
//! the same preferred routing direction. This method will check that in
|
|
//! every GCell of the segment, at least \c reserve tracks are still avalaible
|
|
//! \e after the segment has been moved up (\c reserve can be less than
|
|
//! \c 1.0).
|
|
//!
|
|
//! Possible (bitwise) value for \c flags :
|
|
//! - \c KbAllowTerminal : allow strong terminal to be moved up.
|
|
//! - \c KbAllowLocal : allow local segments to be moved up.
|
|
//! - \c KbPropagate : perform the check on the whole aligned set.
|
|
//! - \c KbWithPerpands : also check the density on the perpandiculars
|
|
//! begin & end GCell, there must be at least a \c 0.5 density
|
|
//! reserve on them.
|
|
|
|
//! \function bool AutoSegment::canPivotUp( float reserve, unsigned int flags ) const;
|
|
//! \param reserve Number of track that must remains free \e after the move.
|
|
//! \param flags Modificate the method behavior, see below.
|
|
//!
|
|
//! Checks of the segment can be \e pivoted up. The difference between
|
|
//! \c canMoveUp() and \c canPivotUp() lies in the fact that no
|
|
//! perpandicular segment needs to be altered if the current segment
|
|
//! is moved up. For example an \b M3 segment connected to only \b M4 can
|
|
//! be pivoted up (in \b M5), but if connected to \b M2, it cannot.
|
|
//!
|
|
//! Possible (bitwise) value for \c flags :
|
|
//! - \c KbPropagate : perform the check on the whole aligned set.
|
|
//! - \c KbIgnoreContacts : do not check the source & target layers
|
|
//! to know if the segment can be pivoted up.
|
|
|
|
//! \function bool AutoSegment::canPivotDown( float reserve, unsigned int flags ) const;
|
|
//! \param reserve Number of track that must remains free \e after the move.
|
|
//! \param flags Modificate the method behavior, see below.
|
|
//!
|
|
//! Checks of the segment can be \e pivoted down. The difference between
|
|
//! \c canMoveDown() and \c canPivotDown() lies in the fact that no
|
|
//! perpandicular segment needs to be altered if the current segment
|
|
//! is moved down.
|
|
//!
|
|
//! Possible (bitwise) value for \c flags :
|
|
//! - \c KbPropagate : perform the check on the whole aligned set.
|
|
|
|
//! \function bool AutoSegment::checkPositions() const;
|
|
//! \sreturn \true if the relative positions of source & target are coherent.
|
|
//! (source <= target).
|
|
|
|
//! \function bool AutoSegment::checkConstraints() const;
|
|
//! \sreturn \true if the constraint intervel is coherent (non-empty or
|
|
//! punctual in the worst case).
|
|
|
|
//! \function unsigned long AutoSegment::getId() const;
|
|
//! \sreturn The AutoSegment unique identifier.
|
|
|
|
//! \function unsigned int AutoSegment::getDirection() const;
|
|
//! \sreturn Katabatic::KbHorizontal or Katabatic::KbVertical according to the decorated segment.
|
|
|
|
//! \function GCell* AutoSegment::getGCell() const;
|
|
//! \sreturn The GCell into which the AutoSegment starts (the one of the source).
|
|
|
|
//! \function size_t AutoSegment::getGCells( vector<GCell*>& gcells ) const;
|
|
//! \param gcells A vector that will be filled by all the GCells that the
|
|
//! segment overlap. In increasing order, from source to target.
|
|
//! \return The vector's size.
|
|
|
|
//! \function AutoContact* AutoSegment::getAutoSource() const;
|
|
//! \sreturn The source AutoContact.
|
|
|
|
//! \function AutoContact* AutoSegment::getAutoTarget() const;
|
|
//! \sreturn The target AutoContact.
|
|
|
|
//! \function AutoContact* AutoSegment::getOppositeAnchor( AutoContact* contact ) const;
|
|
//! \sreturn The source or target AutoContact opposite to \c contact.
|
|
|
|
//! \function size_t AutoSegment::getPerpandicularsBound( set<AutoSegment*>& bounds );
|
|
//! \param bounds A vector that will be filled by all the AutoSegments perpandicular
|
|
//! to this one that induce a constraint.
|
|
//! \return The vector's size.
|
|
|
|
//! \function AutoSegment* AutoSegment::getParent() const;
|
|
//! \sreturn If this segment has been created by a dogleg operation, the parent is
|
|
//! the one from which we fragmented.
|
|
|
|
//! \function DbU::Unit AutoSegment::getAxis() const;
|
|
//! \sreturn The AutoSegment axis position.
|
|
|
|
//! \function DbU::Unit AutoSegment::getSourceU() const;
|
|
//! \sreturn The AutoSegment \e uniform source position. (X for an horizontal and
|
|
//! Y for a Vertical).
|
|
|
|
//! \function DbU::Unit AutoSegment::getTargetU() const;
|
|
//! \sreturn The AutoSegment \e uniform target position. (X for an horizontal and
|
|
//! Y for a Vertical).
|
|
|
|
//! \function DbU::Unit AutoSegment::getDuSource() const;
|
|
//! \sreturn The AutoSegment \e uniform delta from source. (dX for an horizontal and
|
|
//! dY for a Vertical).
|
|
|
|
//! \function DbU::Unit AutoSegment::getDuTarget() const;
|
|
//! \sreturn The AutoSegment \e uniform delta from source. (dX for an horizontal and
|
|
//! dY for a Vertical).
|
|
|
|
//! \function DbU::Unit AutoSegment::getOrigin() const;
|
|
//! \sreturn The AutoSegment \e uniform source (lowest) GCell coordinate. (dX for an horizontal and
|
|
//! dY for a Vertical).
|
|
|
|
//! \function DbU::Unit AutoSegment::getExtremity() const;
|
|
//! \sreturn The AutoSegment \e uniform target (greatest) GCell coordinate. (dX for an horizontal and
|
|
//! dY for a Vertical).
|
|
|
|
//! \function Interval AutoSegment::getSpanU() const;
|
|
//! \sreturn The AutoSegment \e uniform occupying interval (on X for horizontal and
|
|
//! on Y for vertical).
|
|
|
|
//! \function Interval AutoSegment::getSourceConstraints( unsigned int flags ) const;
|
|
//! \return The Interval into witch the source AutoContact can vary. By default
|
|
//! all deduced constraints and user constraints are took into account.
|
|
//! If \c flags contains \c KbNativeConstraints the constraint returned is
|
|
//! only the enclosing GCell.
|
|
|
|
//! \function Interval AutoSegment::getTargetConstraints( unsigned int flags ) const;
|
|
//! \return The Interval into witch the target AutoContact can vary. By default
|
|
//! all deduced constraints and user constraints are took into account.
|
|
//! If \c flags contains \c KbNativeConstraints the constraint returned is
|
|
//! only the enclosing GCell.
|
|
|
|
//! \function bool AutoSegment::getConstraints( DbU::Unit& min, DbU::Unit& max ) const;
|
|
//! \sreturn in \c min & \c max the allowed range for the segment axis.
|
|
|
|
//! \function bool AutoSegment::getConstraints( Interval& i ) const;
|
|
//! \sreturn in \c i the allowed range for the segment axis.
|
|
|
|
//! \function const Interval& AutoSegment::getUserConstraints() const;
|
|
//! \sreturn A reference to the additional constraints added to the axis of the segment.
|
|
|
|
//! \function DbU::Unit AutoSegment::getSlack() const;
|
|
//! \sreturn The length of the axis constraint interval.
|
|
|
|
//! \function DbU::Unit AutoSegment::getOptimalMin() const;
|
|
//! \sreturn The AutoSegment minimum axis optimal range.
|
|
|
|
//! \function DbU::Unit AutoSegment::getOptimalMax() const;
|
|
//! \sreturn The AutoSegment maximum axis optimal range.
|
|
|
|
//! \function Interval& AutoSegment::getOptimal( Interval& i ) const;
|
|
//! Inialize \c i with the AutoSegment axis optimal range.
|
|
|
|
//! \function DbU::Unit AutoSegment::getCost( DbU::Unit axis ) const;
|
|
//! \return The cost if this segment is placed at \c axis. The cost is null if
|
|
//! \c axis is inside the optimal interval and is the distance toward
|
|
//! the nearest bound outside.
|
|
|
|
//! \function AutoSegment* AutoSegment::getCanonical( Interval& i );
|
|
//! \return The canonical segment associated to this one. Additionnaly compute
|
|
//! the source & target position of the whole set of aligned segments.
|
|
|
|
//! \function AutoSegment* AutoSegment::getCanonical( DbU::Unit& min, DbU::Unit& max );
|
|
//! \return The canonical segment associated to this one. Additionnaly compute
|
|
//! the source & target position of the whole set of aligned segments.
|
|
|
|
//! \function unsigned int AutoSegment::_getFlags () const;
|
|
//! Sets \c flags given as arguments.
|
|
|
|
//! \function void AutoSegment::setFlags ( unsigned int flags );
|
|
//! Sets \c flags given as arguments.
|
|
|
|
//! \function void AutoSegment::unsetFlags ( unsigned int flags );
|
|
//! Unsets \c flags given as arguments.
|
|
|
|
//! \function void AutoSegment::setDuSource( DbU::Unit du );
|
|
//! Set the \e uniform \c dU from source anchor (dX for Horizontal,
|
|
//! dY for Vertical).
|
|
|
|
//! \function void AutoSegment::setDuTarget( DbU::Unit du );
|
|
//! Set the \e uniform \c dU from target anchor (dX for Horizontal,
|
|
//! dY for Vertical).
|
|
|
|
//! \function void AutoSegment::updateOrient ();
|
|
//! Ensure that source is lower than target. Swap them if needed.
|
|
//! Swap never occurs on global segment because their source and target
|
|
//! anchors are from different GCell, which are already ordered.
|
|
|
|
//! \function void AutoSegment::computeTerminal ();
|
|
//! Recompute the terminal status of an AutoSegment. Initially, a
|
|
//! segment which source or target is a terminal is flagged as
|
|
//! SegStrongTerminal. After a topological modification, if the
|
|
//! segment is no longer directly attached to a terminal, the
|
|
//! status is progessively weakened. Once it reaches the weakest
|
|
//! level, it stays on it so the algorithm can work out which
|
|
//! segments is a start to a path toward a terminal.
|
|
//!
|
|
//! Status from stronger to weaker:
|
|
//! - Katabatic::SegStrongTerminal.
|
|
//! - Katabatic::SegWeakTerminal1
|
|
//! - Katabatic::SegWeakTerminal2
|
|
//!
|
|
//! \remark The weakening is poorly done. After making a dogleg we do not
|
|
//! know which of the segment must be weakened if not directly attached
|
|
//! on a terminal. We must examinate source & target.
|
|
|
|
//! \function void AutoSegment::updatePositions();
|
|
//! Update the segment begenning and ending positions. The positions
|
|
//! takes into account the extension caps and reflect the real space
|
|
//! used by the segment under it's long axis.
|
|
|
|
//! \function void AutoSegment::mergeUserConstraints( const Interval& constraints );
|
|
//! Constraints applies on the valid axis interval.
|
|
//! Merge in \c constraints with the user's constraints. The resulting
|
|
//! constraints is the intersection of the former user's contraints and
|
|
//! the one given as argument.
|
|
|
|
//! \function void AutoSegment::resetUserConstraints();
|
|
//! Constraints applies on the valid axis interval.
|
|
//! Suppress all user's constraints.
|
|
|
|
//! \function void AutoSegment::setOptimalMin( DbU::Unit min );
|
|
//! Sets the lower bound of the optimal axis interval.
|
|
|
|
//! \function void AutoSegment::setOptimalMax( DbU::Unit max );
|
|
//! Sets the lower bound of the optimal axis interval.
|
|
|
|
//! \function Interval AutoSegment::_invalidate();
|
|
//! Invalidate this segment. The segment is scheduled into the Session
|
|
//! revalidation mechanism.
|
|
|
|
//! \function Interval AutoSegment::revalidate();
|
|
//! Mark this segment as valid (unset the Invalidated flag) and update
|
|
//! positions. Unlike AutoSegment::invalidate(), it's an atomic method.
|
|
|
|
//! \function Interval AutoSegment::getMinSpanU() const;
|
|
//! \return The AutoSegment \e uniform minimum occupying interval, computed from the
|
|
//! constraints of all the supporting aligned AutoContacts.
|
|
//! (on X for horizontal and on Y for vertical).
|
|
|
|
//! \function AutoSegment* AutoSegment::canonize ( unsigned int flags=KbNoFlags );
|
|
//! Find and set the canonical AutoSegment from a set of aligneds. For the
|
|
//! time beeing we assumes that there is no merging process, so the Segments
|
|
//! will only gets more and more fragmented. This implies that a segment can
|
|
//! become canonical but it will never revert to normal status.
|
|
//!
|
|
//! The canonical AutoSegment is the one with the lowest \c Id. This a way
|
|
//! of ensuring reproductible results. Note that the canonical one may not
|
|
//! be the \e geometrically lowest one.
|
|
//!
|
|
//! \remark Canonical aware method.
|
|
|
|
//! \function Interval AutoSegment::computeOptimal( set<AutoSegment*>& processeds );
|
|
//! \param processeds A set of already processeds AutoSegment. Used by the
|
|
//! caller function to avoid doing again the computation
|
|
//! on an AutoSegment from an already proccessed aligned set.
|
|
//! Compute the optimal axis interval for the aligned set.
|
|
//!
|
|
//! \remark Canonical aware method.
|
|
|
|
//! \function void AutoSegment::invalidate( unsigned int flags=KbPropagate );
|
|
//! Invalidate this AutoSegment, or if the Katabatic::KbPropagate flags
|
|
//! is set, the whole set of aligned segments.
|
|
//!
|
|
//! \remark If Katabatic is in the destruction stage, this function does nothing.
|
|
//! \remark Canonical aware method.
|
|
|
|
//! \function void AutoSegment::setAxis( DbU::Unit axis, unsigned int flags=0 );
|
|
//! \param axis The new position of the axis.
|
|
//! \param flags See KbRealignate.
|
|
//!
|
|
//! Set the axis of an aligned set. This method does nothing if not called
|
|
//! on the canonical AutoSegment of the set. If the new value of the axis
|
|
//! is equal to the previous one, nothing is done (non-canonical AutoSegment
|
|
//! are not looked after). To force an actual axis set, with invalidation of
|
|
//! the whole AutoSegment set, set the KbRealignate flag.
|
|
//!
|
|
//! \remark Canonical aware method.
|
|
|
|
//! \function bool AutoSegment::toConstraintAxis();
|
|
//! If the AutoSegment axis is outside the constraint interval, put it on
|
|
//! nearest bound. This method is active only on canonical AutoSegments.
|
|
//!
|
|
//! \return \true if an actual axis change is made.
|
|
//!
|
|
//! \remark Canonical aware method.
|
|
|
|
//! \function bool AutoSegment::toOptimalAxis();
|
|
//! If the AutoSegment axis is outside the optimal interval, put it on
|
|
//! nearest bound. This method is active only on canonical AutoSegments.
|
|
//!
|
|
//! \return \true if an actual axis change is made.
|
|
//!
|
|
//! \remark Canonical aware method.
|
|
|
|
//! \function AutoSegments AutoSegment::getAligneds ( unsigned int flags );
|
|
//! The Collection of AutoSegments that are aligned on this one
|
|
//! through AutoContactHTee or AutoContactVTee. If the \c flags
|
|
//! contains Katabatic::KbWithPerpands, the Collection will also
|
|
//! includes the AutoSegments directly perpandiculars to the whole
|
|
//! aligned set.
|
|
|
|
//! \function AutoSegments AutoSegment::getPerpandiculars ();
|
|
//! The Collection of all AutoSegments directly perpandiculars to the
|
|
//! whole aligned set.
|
|
|
|
//! \function AutoSegments AutoSegment::getOnSourceContact ( unsigned int direction );
|
|
//! \sreturn The Collection of AutoSegment in \c direction that are on this segment
|
|
//! source contact.
|
|
|
|
//! \function AutoSegments AutoSegment::getOnTargetContact ( unsigned int direction );
|
|
//! \sreturn The Collection of AutoSegment in \c direction that are on this segment
|
|
//! target contact.
|
|
|
|
//! \function AutoSegment::~AutoSegment ()
|
|
//! AutoSegment destructor. It is not directly accessible, instead use
|
|
//! one flavor of the AutoSegment::create().
|
|
|
|
//! \function AutoSegment::AutoSegment ( Segment* segment );
|
|
//! AutoSegment constructor. It is not directly accessible, instead use
|
|
//! one flavor of the AutoSegment::create().
|
|
|
|
//! \function void AutoSegment::_preCreate( AutoContact* source, AutoContact* target );
|
|
//! Perform sanity checks before allowing the actual creation of an
|
|
//! AutoSegment. If an error occurs throw an exception.
|
|
//!
|
|
//! Check for:
|
|
//! - \c source and \c target must not be \NULL.
|
|
//! - \c source and \c target must be different.
|
|
|
|
//! \function void AutoSegment::_postCreate ();
|
|
//! Perform operations that, given the data structure cannot be done
|
|
//! in the constructor. Also allows for sharing code with the derived
|
|
//! classes. Currently:
|
|
//! - Invalidate the whole net (topology change).
|
|
//! - Insert the AutoSegment in the lookup/Session machanism.
|
|
//! - Call AutoSegment::invalidate().
|
|
//! - Call AutoSegment::updateOrient().
|
|
//! - Call AutoSegment::updatePositions().
|
|
|
|
//! \function void AutoSegment::_preDestroy ();
|
|
//! Perform operations that must be done before the actual destructor is
|
|
//! called. Merely whidrawn the AutoSegment from the lookup/Session mechanism.
|
|
|
|
//! \function AutoSegment* AutoSegment::makeDogleg ( AutoContact* from );
|
|
//! \param from The AutoContact \e from which we want to make a dogleg.
|
|
//!
|
|
//! This method is dedicated for the restauration of topology connexity on
|
|
//! AutoContcact after a layer change on one of their connected AutoSegment.
|
|
//!
|
|
//! It perform three operations:
|
|
//! -# Create a dogleg on the AutoSegment (using the normal GCell variant).
|
|
//! -# Adjust the layers of the dogleg according whether we are going \e up
|
|
//! or \e down from the AutoContact \c from to the segment.
|
|
//! -# Returns the new AutoSegment connected to \c from (it may be the
|
|
//! same as before, \b if the AutoContact is the source of the
|
|
//! segment).
|
|
|
|
//! \function unsigned int AutoSegment::makeDogleg ( GCell* doglegGCell, unsigned int flags=KbNoFlags );
|
|
//! Make a dogleg <em>in a set of aligned segments</em>, thus the dogleg
|
|
//! may not be created on \c this segment but in the one which is under
|
|
//! \c doglegGCell.
|
|
//!
|
|
//! \sreturn A flag telling if the above or below layer was used for the
|
|
//! perpandicular segment (Katabatic::KbUseAboveLayer or
|
|
//! Katabatic::KbUseBelowLayer).
|
|
|
|
//! \function unsigned int AutoSegment::makeDogleg ( Interval interval, unsigned int flags=KbNoFlags );
|
|
//! Make a dogleg <em>in a set of aligned segments</em>, thus the dogleg
|
|
//! may not be created on \c this segment but in one which span intersect
|
|
//! \c interval.
|
|
//!
|
|
//! \sreturn A set of flags telling if the break has occured on the left candidate
|
|
//! (Katabatic::KbDoglegOnLeft) or right (Katabatic::KbDoglegOnRight).
|
|
//! it is combined with the flag telling if the above or below layer was
|
|
//! used for the dogleg. In case of failure, zero is returned.
|
|
//!
|
|
//! Break the set of aligned segments so the break point is \e outside
|
|
//! \c interval. The break point so can occurs on the \e left of the
|
|
//! interval (Katabatic::KbDoglegOnLeft) or on the \e right of the
|
|
//! interval (Katabatic::KbDoglegOnRight). When the set of aligned
|
|
//! segments fully enclose \c interval, a choice has to be made between
|
|
//! the left and right candidate. The rules are as follow:
|
|
//! - A \e left candidate include the \e min of the interval into
|
|
//! it's span.
|
|
//! - A \e right candidate include the \e max of the interval into
|
|
//! it's span.
|
|
//! - In certain topologies, there can be more than left or right
|
|
//! candidates (more than one segment of the set intersect the
|
|
//! bounds of the interval). Thoses candidates are ecludeds.
|
|
//! - If the two candidates are avalaibles, we choose the one
|
|
//! with the greated \e native constraints.
|
|
//! - In case of strict equality, the left candidate is choosen.
|
|
//!
|
|
//! \image html _makeDogleg-4.png "Example Case 4"
|
|
|
|
//! \function unsigned int AutoSegment::_makeDogleg ( GCell* doglegGCell, unsigned int flags );
|
|
//! <b>This method is the workhorse for the various dogleg and topology
|
|
//! restauration methods.</b> It is the atomic method that actually
|
|
//! make the dogleg on \b this segment.
|
|
//!
|
|
//! \sreturn Katabatic::KbUseAboveLayer if the dogleg is using the \e above layer
|
|
//! (Katabatic::KbUseBelowLayer for the below layer).
|
|
//!
|
|
//! Break the current segment in two (a.k.a. making a dogleg).
|
|
//! - The segment is broken inside \c doglegGCell.
|
|
//! - Two new segments are createds, one perpandicular and one parallel.
|
|
//! - The original segment is always kept attached to the \e source.
|
|
//! (the new parallel fragment is attached to the \e target).
|
|
//! - The perpandicular segment is in the layer \e above by default.
|
|
//! If we are already on the topmost routing layer, the \e below
|
|
//! layer is used.
|
|
//! - If the segment pass through the breaking GCell, it's axis is set
|
|
//! into the center. If the segment is local, the axis is the middle
|
|
//! of the segment.
|
|
//! - The Local/Global kind of the original segment is updated.
|
|
//! The local/global status is computed by the constructor of the AutoSegment
|
|
//! for the perpandicular and the new parallel.
|
|
//! - The terminal state is updated. If the segment is a strong terminal
|
|
//! the part that is no longer directly connected to the terminal is
|
|
//! demoted to Katabatic::SegWeakTerminal1.
|
|
//! - The perpandicular is obviously a canonical. If the broken segment
|
|
//! is canonical, the original \b is left canonical and only the new parallel
|
|
//! is re-canonized. Otherwise, we re-canonise both sets of aligned segments
|
|
//! (the one on the source and the one on the target).
|
|
//! - The three segments are added to the session dogleg stack.
|
|
//!
|
|
//! \red{After this method call the net topology is guarantee to be valid.}
|
|
//!
|
|
//! \image html _makeDogleg-1.png "Example Case 1"
|
|
//! \image html _makeDogleg-2.png "Example Case 2"
|
|
|
|
//! \function bool AutoSegment::moveULeft ();
|
|
//! <b>This function do not manage an aligned set. It applies on \c this
|
|
//! segment only.</b>
|
|
//!
|
|
//! Displace an Horizontal or Vertical segment to the GCell below (a.k.a.
|
|
//! lower or inferior). Rules for displacement:
|
|
//! - The segment must be connected at both end to a turn contact
|
|
//! (we do not want to manage more complex cases for the time beeing).
|
|
//! - And, of course, the segment must not already by on the bottomost
|
|
//! GCell...
|
|
//!
|
|
//! The displacement take care of:
|
|
//! - Managing the status of the various perpandiculars. The stretched
|
|
//! one are made global if needed. The shrinked one made local, if
|
|
//! needed.
|
|
//! - The supporting AutoContact (source & target) are changed of
|
|
//! GCell.
|
|
//! - If the segment is global, the go-through GCells are updateds.
|
|
//!
|
|
//! \sreturn \true if the move has succeeded.
|
|
//!
|
|
//! \image html moveULeft-1.png "moveULeft() for an Horizontal"
|
|
|
|
//! \function bool AutoSegment::moveURight ();
|
|
//! <b>This function do not manage an aligned set. It applies on \c this
|
|
//! segment only.</b>
|
|
//!
|
|
//! Displace an Horizontal or Vertical segment to the GCell above (a.k.a.
|
|
//! upper or superior). Rules for displacement:
|
|
//!
|
|
//! \sa AutoSegment::moveULeft() for a complete description.
|
|
|
|
//! \function void AutoSegment::slacken ( unsigned int flags );
|
|
//!
|
|
//! If the the AutoSegment is attached trough source and/or target to a
|
|
//! terminal with too tight constraints, create a dogleg on overconstrained
|
|
//! extremities.
|
|
//!
|
|
//! If \c flags contains Katabatic::KbPropagate, not only the current segment will be
|
|
//! looked up, but the whole aligned set. Note that due to the structure of
|
|
//! the database, there can be no more than two terminal connected segments
|
|
//! on the whole set (one on each extremity).
|
|
//!
|
|
//! If \c flags contains Katabatic::KbHalfSlacken, the number of tracks under which
|
|
//! the constraints are considered too tight is 3. Otherwise it is 10, that is a
|
|
//! whole GCell side span. This flag should be used when a long set of global
|
|
//! wire is overconstrained by only one of it's terminal, the other one offering
|
|
//! sufficient slack (typically: 8).
|
|
//!
|
|
//! The segment will also be slackened from it's terminal if the difference
|
|
//! between the current slack (resulting from all the constraints of the
|
|
//! aligned set) and the native slack is less than 3 tracks. This case means
|
|
//! that we are already near the native slack and it not sufficent enough
|
|
//! a degree of freedom.
|
|
//!
|
|
//! \image html _slacken-1.png "slacken() for an Horizontal"
|
|
//!
|
|
//! The \c slacken() method reject the slackening of short locals as shown in
|
|
//! figure \b 2.a. One way or another, we must connect to the terminal through
|
|
//! \b this short local. If we cannot place it, breaking it in two other
|
|
//! short local wouldn't help. In fact, it will only clutter more the GCell
|
|
//! and make subsequent routing more difficult.
|
|
//!
|
|
//! The figures \b 2.b and \b 2.c shows the special case of slackening an
|
|
//! horizontal from an \e horizontal terminal. In the original configuration,
|
|
//! the slack on segment \c id:10 is null, it's only choice is to be aligned
|
|
//! with the terminal. If a slackening is requested, it generally implies that
|
|
//! the horizontal track is blocked, and close to the terminal. Based on thoses
|
|
//! hypothesis, when we slacken the segment \c id:10 we impose that the
|
|
//! \e source contact is \b fixed on the terminal itself. That is, the segment
|
|
//! \c id:10 will be reduced to a zero-length and we made an immediate turn
|
|
//! (see \b 2.c ).
|
|
//!
|
|
//! \image html _slacken-2.png "slacken() for an Horizontal (special cases)"
|
|
|
|
}
|