444 lines
21 KiB
C++
444 lines
21 KiB
C++
|
|
// -*- C++ -*-
|
|
|
|
namespace Katabatic {
|
|
|
|
/*! \class AutoContact
|
|
*
|
|
* \brief Abstract base class for AutoContact
|
|
*
|
|
* \section secACCache Caching Mechanism
|
|
*
|
|
* To bypass the Ring/Hook mechanism \e and the subsequent Session::Lookup()
|
|
* call, the AutoSegments anchored on an AutoContact are cached in the
|
|
* AutoContact itself. They can be accessed through \c getHorizontalN() and
|
|
* getVerticalN() accessors \c N depending on the subtype of AutoContact.
|
|
*
|
|
* Cached AutoSegments are updated in the AutoContact::updateTopology()
|
|
* function only.
|
|
*
|
|
*
|
|
* \section secACInvalidate Invalidate on AutoContacts
|
|
*
|
|
* The invalidation of an AutoContact invalidate all the segments
|
|
* that are anchored on it.
|
|
*
|
|
* <b>Special Case of HTee & VTee</b>
|
|
*
|
|
* When invalidating an HTee or VTee, two out of the three anchored
|
|
* segments are parallels. The \e aligned constraint is passed on
|
|
* those two. By default, when we invalidate an AutoSegment, the
|
|
* invalidation is applied to the whole aligned set through the
|
|
* AutoSegment::getAligneds() collection. So if one of the parallel
|
|
* is invalidated and the other not, it should only be because we
|
|
* are already in \c getAligneds(), then we do not want to invalidate
|
|
* again the whole aligned set. In that case, we perform an atomic only
|
|
* invalidation (reset Katabatic::KbPropagate).
|
|
*
|
|
* For the complete invalidation/revalidation mechanism see
|
|
* \ref secSessionAlgo "Session Algorithm".
|
|
*
|
|
*
|
|
* \section secDiffFromKatabatic2 Notes - Differences from Katabatic 2
|
|
*
|
|
* From the previous version of Katabatic, AutoContact have
|
|
* been greatly stripped down (again). They are now always punctual
|
|
* objetcs with stricly fixed topologies:
|
|
* <ul>
|
|
* <li>AutoContactTerminal to connect to a terminal (one segment).
|
|
* <li>AutoContactTurn to make a turn: two perpandiculars segments.
|
|
* <li>AutoContactHTee an horizontal tee: two \e aligned horizonals
|
|
* and one vertical.
|
|
* <li>AutoContactVTee an horizontal tee: two \e aligned verticals
|
|
* and one horizontal.
|
|
* </ul>
|
|
*/
|
|
|
|
//! \enum AutoContactFlag
|
|
//! Set of flags to describe the internal state of an AutoContact.
|
|
|
|
//! \var AutoContactFlag::CntFixed
|
|
//! This contact cannot be moved.
|
|
|
|
//! \var AutoContactFlag::CntTerminal
|
|
//! This contact is anchored on a terminal (AutoContactTerminal), <b>must not be changed</b>.
|
|
|
|
//! \var AutoContactFlag::CntTurn
|
|
//! The object true class is AutoContactTurn, <b>must not be changed</b>.
|
|
|
|
//! \var AutoContactFlag::CntHTee
|
|
//! The object true class is AutoContactHTee, <b>must not be changed</b>.
|
|
|
|
//! \var AutoContactFlag::CntVTee
|
|
//! The object true class is AutoContactVTee, <b>must not be changed</b>.
|
|
|
|
//! \var AutoContactFlag::CntInvalidated
|
|
//! At least one AutoSegment of this contact has been moved, the contact
|
|
//! position must be recomputed (in the Session revalidation).
|
|
|
|
//! \var AutoContactFlag::CntInvalidatedCache
|
|
//! At least one AutoSegment has been broken or moved up, the connexity
|
|
//! must be checked and possibly corrected (in Session revalidation).
|
|
|
|
//! \var AutoContactFlag::CntInCreationStage
|
|
//! Sets only during the initial creation process.
|
|
|
|
//! \var AutoContactFlag::CntBadTopology
|
|
//! Something wrong has happened and the connexity of the AutoContact is
|
|
//! no longer ensured (too much or too less AutoSegments, too wide span of
|
|
//! AutoSegment layers).
|
|
|
|
//! \function Hook* AutoContact::getBodyHook ();
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function Hook* AutoContact::getAnchorHook ();
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function Component* AutoContact::getAnchor () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function Net* AutoContact::getNet () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function const Layer* AutoContact::getLayer () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function DbU::Unit AutoContact::getX () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function DbU::Unit AutoContact::getY () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function DbU::Unit AutoContact::getDx () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function DbU::Unit AutoContact::getDy () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function Point AutoContact::getCenter () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function Point AutoContact::getPosition () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function DbU::Unit AutoContact::getWidth () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function DbU::Unit AutoContact::getHalfWidth () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function DbU::Unit AutoContact::getHeight () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function DbU::Unit AutoContact::getHalfHeight () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function Components AutoContact::getSlaveComponents () const;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setLayer ( const Layer* ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setWidth ( DbU::Unit ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setHeight ( DbU::Unit ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setSizes ( DbU::Unit w, DbU::Unit h ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setX ( DbU::Unit ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setY ( DbU::Unit ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setPosition ( DbU::Unit w, DbU::Unit h ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setPosition ( const Point& ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setDx ( DbU::Unit ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setDy ( DbU::Unit ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::setOffset ( DbU::Unit w, DbU::Unit h ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function void AutoContact::translate ( const DbU::Unit& dx, const DbU::Unit& dy ) ;
|
|
//! <em>Base class method proxy.</em>
|
|
|
|
//! \function bool AutoContact::isInCreationStage () const;
|
|
//! \sreturn \true if the AutoContact is still in it's initial creation stage.
|
|
|
|
//! \function bool AutoContact::isInvalidated () const;
|
|
//! \sreturn \true if the some AutoSegment has changed and the AutoContact needs
|
|
//! to be repositionned (through a call to AutoContact::updateGeometry()).
|
|
|
|
//! \function bool AutoContact::isInvalidatedCache () const;
|
|
//! \sreturn \true if the some AutoSegment has changed and the AutoContact
|
|
//! topology needs to be restored, as a gap may have appeared
|
|
//! (through a call to AutoSegment::updateTopology()).
|
|
|
|
//! \function bool AutoContact::isTurn () const;
|
|
//! \sreturn \true if the dynamic type of the AutoContact is of type Turn.
|
|
|
|
//! \function bool AutoContact::isTee ( unsigned int direction ) const;
|
|
//! \sreturn \true if the dynamic type of the AutoContact is either of type
|
|
//! AutoContactHTee or AutoContactVTee, according to \c direction.
|
|
|
|
//! \function bool AutoContact::isHTee () const;
|
|
//! \sreturn \true if the dynamic type of the AutoContact is of type AutoContactHTee.
|
|
|
|
//! \function bool AutoContact::isVTee () const;
|
|
//! \sreturn \true if the dynamic type of the AutoContact is of type AutoContactHTee.
|
|
|
|
//! \function bool AutoContact::isFixed () const;
|
|
//! \sreturn \true if the AutoContact cannot be moved.
|
|
|
|
//! \function bool AutoContact::hasBadTopology () const;
|
|
//! \sreturn \true if the AutoContact topology has been broken and a gap has appeared.
|
|
//! (sould not happen...)
|
|
|
|
//! \function bool AutoContact::canDestroy ( unsigned int flags ) const;
|
|
//! \sreturn \true if the AutoContact could be destroyed, that is, no segments
|
|
//! remains anchored on it. If \c flags contains Katabatic::KbWarnOnError,
|
|
//! issue an error message.
|
|
|
|
//! \function bool AutoContact::canMoveUp ( const AutoSegment* moved ) const;
|
|
//! \sreturn \true if \c segment can be moved up without triggering a topological
|
|
//! modification. It meaans that:
|
|
//! - Without \c moved, the AutoContact needs only one layer.
|
|
//! - \c moved go from \e below the AutoContact to \e above.
|
|
|
|
//! \function Contact* AutoContact::base () const;
|
|
//! \sreturn The Hurricane::Contact which is decorated.
|
|
|
|
//! \function size_t AutoContact::getAllocateds ();
|
|
//! \sreturn The total number of AutoContact currently allocateds.
|
|
|
|
//! \function const Name& AutoContact::getStaticName ();
|
|
//! \sreturn The name of the Hurricane::ExtensionGo slice.
|
|
|
|
//! \function const Name& AutoContact::getName () const;
|
|
//! \sreturn The name of the Hurricane::ExtensionGo slice.
|
|
|
|
//! \function const Name& AutoContact::getId () const;
|
|
//! \sreturn The unique \c identifer of the AutoSegment.
|
|
|
|
//! \function Box AutoContact::getBoundingBox () const;
|
|
//! \see Contact::getBoundingBox().
|
|
|
|
//! \function GCell* AutoContact::getGCell () const;
|
|
//! \sreturn The GCell into which the AutoContact is located.
|
|
|
|
//! \function AutoSegment* AutoContact::getOpposite ( const AutoSegment* reference ) const;
|
|
//! \sreturn The other AutoSegment the \e same direction as \c reference, this is
|
|
//! only meaningful on AutoContactHTee or AutoContactVTee. If there is
|
|
//! no opposite, \c NULL is returned.
|
|
|
|
//! \function AutoSegment* AutoContact::getPerpandicular ( const AutoSegment* reference ) const;
|
|
//! \sreturn The AutoSegment in the \e perpandicular direction to \c reference, this is
|
|
//! only meaningful on AutoContacTurn. It there is no unique perpandicular,
|
|
//! \c NULL is returned.
|
|
|
|
//! \function AutoSegment* AutoContact::getSegment ( unsigned int index ) const;
|
|
//! \sreturn The nth anchored AutoSegment. The index is significant:
|
|
//! - \b 0 : first horizontal (\b h1).
|
|
//! - \b 1 : second horizontal (\b h2).
|
|
//! - \b 2 : first vertical (\b b1).
|
|
//! - \b 3 : second vertical (\b b2).
|
|
//!
|
|
//! Not all the indexes are filled for every AutoContact. For example
|
|
//! \c Turn have \b h1 and \b b1, and \c HTee have \b h1, \b h2 and
|
|
//! \b v1.
|
|
|
|
//! \function unsigned int AutoContact::getMinDepth () const;
|
|
//! \sreturn The layer depth of the bottom layer of the AutoContact.
|
|
|
|
//! \function unsigned int AutoContact::getMaxDepth () const;
|
|
//! \sreturn The layer depth of the top layer of the AutoContact.
|
|
|
|
//! \function void AutoContact::getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& processeds );
|
|
//! \param lengths A table of DbU::Unit, the size of all routing layers used.
|
|
//! \param processeds An AutoSegment sorted set holding all the already processeds
|
|
//! AutoSegments.
|
|
//!
|
|
//! Compute the lengths over the owning GCell of all the AutoSegments anchored
|
|
//! on this AutoContact. The lengths are added to the total length table
|
|
//! \c lengths. To avoid double accounting of the local AutoSegments
|
|
//! that have both source & target in the same GCell, we keep a set
|
|
//! of already processeds AutoSegments in \c processeds.
|
|
|
|
//! \function Box AutoContact::getNativeConstraintBox () const;
|
|
//! \sreturn The native constraint box (that is, whithout any user constraints
|
|
//! applied). For AutoContactTerminal, this is the Box of the supporting
|
|
//! external component, and for all others the bounding box of the
|
|
//! owning GCell.
|
|
|
|
//! \function Interval AutoContact::getUConstraints ( unsigned int direction ) const;
|
|
//! \sreturn The constraint interval in \c direction (that is, the relevant side
|
|
//! of the constraint box).
|
|
|
|
//! \function DbU::Unit AutoContact::getCBXMin () const;
|
|
//! \sreturn The X coordinate of the bottom left corner of the constraint box.
|
|
|
|
//! \function DbU::Unit AutoContact::getCBYMin () const;
|
|
//! \sreturn The Y coordinate of the bottom left corner of the constraint box.
|
|
|
|
//! \function DbU::Unit AutoContact::getCBXMax () const;
|
|
//! \sreturn The X coordinate of the top right corner of the constraint box.
|
|
|
|
//! \function DbU::Unit AutoContact::getCBYMax () const;
|
|
//! \sreturn The Y coordinate of the top right corner of the constraint box.
|
|
|
|
//! \function Box AutoContact::getConstraintBox () const;
|
|
//! \sreturn The current constraint box: the native constraint box with all
|
|
//! the user's contraints applieds.
|
|
|
|
//! \function Box& AutoContact::intersectConstraintBox ( Box& box ) const;
|
|
//! \sreturn The intersection between \c box and the constraint box. The
|
|
//! result is stored into \c box and a reference to it is returned.
|
|
|
|
//! \function void AutoContact::invalidate ( unsigned int flags=0 );
|
|
//! Invalidate the AutoContact, schedule it for revalidation in the
|
|
//! Session. If flag containt Katabatic::CntInvalidTopology,
|
|
//! the topology of the AutoContact will also be checked and
|
|
//! possible gap closeds.
|
|
//!
|
|
//! The revalidations methods associated are:
|
|
//! - AutoSegment::updateGeometry(), recompute the punctual contact position.
|
|
//! - AutoSegment::updateTopology(), restore the connexity.
|
|
|
|
//! \function void AutoContact::updateGeometry ();
|
|
//! Compute the new position of the AutoContact based on the AutoSegment
|
|
//! positions. The Session mechanism ensure that all AutoSegment are
|
|
//! set into their final positions before calling this updator.
|
|
|
|
//! \function void AutoContact::updateTopology ();
|
|
//! Modificate the AutoContact topology to close any gap. This could
|
|
//! be by changing layer or creating a new dogleg on an incident
|
|
//! AutoSegment.
|
|
|
|
//! \function void AutoContact::_getTopology ( Component*& anchor, Horizontal**& hs, Vertical**& vs, size_t sz );
|
|
//! \param anchor The anchor, if any.
|
|
//! \param hs The Hurricane::Horizontal anchored.
|
|
//! \param vs The Hurricane::Vertical anchored.
|
|
//! \param sz The size of boths \c hs & \c vs table passed as arguments.
|
|
//!
|
|
//! Fill \c anchor , \c hs and \c vs with the components anchored on this
|
|
//! AutoContact.
|
|
|
|
//! \function void AutoContact::showTopologyError ( const std::string& message );
|
|
//! Comprensive display of the topology of the AutoContact to ease the
|
|
//! debug work. Prepend with the error message \c message. Do no throw
|
|
//! an error.
|
|
|
|
//! \function void AutoContact::checkTopology ();
|
|
//! Check for topology correctness (no gaps), display an error message
|
|
//! if needed.
|
|
|
|
//! \function void AutoContact::setGCell ( GCell* gcell );
|
|
//! Set the owning GCell.
|
|
|
|
//! \function void AutoContact::setCBXMin ( DbU::Unit xMin );
|
|
//! Set the lower left X coordinate of the constraint box.
|
|
//!
|
|
//! \remark It cannot go outside the GCell bounding box.
|
|
|
|
//! \function void AutoContact::setCBYMin ( DbU::Unit yMin );
|
|
//! Set the lower left Y coordinate of the constraint box.
|
|
//!
|
|
//! \remark It cannot go outside the GCell bounding box.
|
|
|
|
//! \function void AutoContact::setCBXMax ( DbU::Unit xMax );
|
|
//! Set the upper right X coordinate of the constraint box.
|
|
//!
|
|
//! \remark It cannot go outside the GCell bounding box.
|
|
|
|
//! \function void AutoContact::setCBYMax ( DbU::Unit yMax );
|
|
//! Set the upper right Y coordinate of the constraint box.
|
|
//!
|
|
//! \remark It cannot go outside the GCell bounding box.
|
|
|
|
//! \function void AutoContact::setConstraintBox ( const Box& box );
|
|
//! Set the constraint box.
|
|
//!
|
|
//! \remark It cannot go outside the GCell bounding box.
|
|
|
|
//! \function bool AutoContact::restrictConstraintBox ( DbU::Unit min, DbU::Unit max, unsigned int flags=KbWarnOnError );
|
|
//! \param min The minimum of the restriction interval.
|
|
//! \param max The maximum of the restriction interval.
|
|
//! \param flags Gives the direction of the restriction.
|
|
//! \return \true if the restriction was actually applied.
|
|
//!
|
|
//! Restrict the current constraint box but check if the restriction
|
|
//! will not lead to an empty interval, in that case, do nothing and
|
|
//! return \false.
|
|
|
|
//! \function void AutoContact::migrateConstraintBox ( AutoContact* other );
|
|
//! Transfer the user constraint box from \c other to the current
|
|
//! object \c this. The constraints of \c other are restored to their
|
|
//! native values. The two contacts must belong to the same GCell for
|
|
//! this method to take effect.
|
|
|
|
|
|
/*! \class LocatorHelper
|
|
*
|
|
* \brief Locator Helper Collection's Locators
|
|
*
|
|
* Provide a small uniform walktough over the AutoSegments anchored
|
|
* on AutoContacts. The \c flags argument allows to choose between
|
|
* direction and include perpandiculars (in that case all segments
|
|
* are processeds).
|
|
*
|
|
*
|
|
* \section secLocHelperImplementation Implementation Details
|
|
*
|
|
* As, at most, two horizontals and two verticals may be anchored on
|
|
* any AutoContact subtype, the locator helper perform a walk through
|
|
* a virtual table of 4 elements. The two first are the horizontals,
|
|
* the two last the verticals. The meaning of this index is consistent
|
|
* whith the \c index argument of AutoContact::getSegment(). When
|
|
* a segment is not present in an AutoContact, the \c getSegment()
|
|
* returns \c NULL and the LocatorHelper::progress() function will
|
|
* skip it.
|
|
*
|
|
* The private methods:
|
|
* - \c LocatorHelper::_min()
|
|
* - \c LocatorHelper::_max()
|
|
*
|
|
* Computes the bounds of \c _index according to the value of \c _flags:
|
|
* - \c KbHorizontal : \c 0 to less than \c 2.
|
|
* - \c KbVertical : \c 2 to less than \c 4.
|
|
* - \c KbHorizontal|KbVertical : \c 0 to less than \c 4.
|
|
*/
|
|
|
|
//! \function LocatorHelper::LocatorHelper ( AutoContact* contact, unsigned int flags );
|
|
//! Create a helper to iterate over the AutoSegments anchored on \c contact.
|
|
//! The \c flags arguments allow to select:
|
|
//! - The direction: Katabatic::KbHorizontal or Katabatic::KbVertical.
|
|
//! - Perpandicular inclusion: Katabatic::KbWithPerpands.
|
|
//!
|
|
//! When setting KbWithPerpands, all the segments will be iterated over.
|
|
//! It may seems a somewhat contorted way of doing things, the reason is
|
|
//! the ability to share (an pass) flags directly between different
|
|
//! functions.
|
|
|
|
//! \function bool LocatorHelper::isValid() const;
|
|
//! \sreturn \true if there is an AutoSegment to be processed.
|
|
|
|
//! \function AutoSegment* LocatorHelper::getSegment() const;
|
|
//! \sreturn The current AutoSegment. \c NULL if the loop is over.
|
|
|
|
//! \function void LocatorHelper::progress();
|
|
//! \sreturn Go to the next AutoSegment.
|
|
|
|
}
|
|
|
|
|