// -*- 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 * * * * The Ever Fragmenting Data Structure * * 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 * * * * * \section secASInvalidate Invalidate on AutoSegments * * The simple invalidation of an AutoSegment do not invalidate * it's source & target contact. * * An axis position change or a layer change both invalidate the * AutoSegment and 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. * * * * \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 * * * * * */ //! \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::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 or the stem part of a tee. //! \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& 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& 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& 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 in a set of aligned segments, 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 in a set of aligned segments, 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 ); //! This method is the workhorse for the various dogleg and topology //! restauration methods. 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 (); //! This function do not manage an aligned set. It applies on \c this //! segment only. //! //! 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 (); //! This function do not manage an aligned set. It applies on \c this //! segment only. //! //! 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)" }