// -*- C++ -*- namespace Katabatic { /*! \class GCell * * \brief Routing Global Cell * * * \section secGCellDescription GCell Description * * Please note that there are two kind of Global Cells (or GCell for short): * - The GCell used by the global router Knik. * - The GCell used by the detailed router (Katabatic & Kite). * Although the information they hold is obviously related, they are two * separate kind of objects. * * The area of the design to be routed is divided in a regular grid of * rectangular area, the GCellGrid. Each rectangular area is a GCell. * * The GCell contains the following informations: * - The AutoSegments that begins or ends in it. The list of segments * is not avalaible directly but through the AutoContacts that are * owned by the GCell. * - The AutoSegments that go straight \e through it (or \e over it). * Horizontal & Vertical segments are stored in two separeted list. * Those two lists are sorted by layer depth (the deepest layers * first). * - A lot of synthetic information about the density of tracks used * in the GCell. * * AutoContacts are affected to GCells, the area of the GCell is the * one into which the AutoContact is allowed to be placed. It is this * that way that the respect of the global routing choosen by Knik is * enforced. See the AutoContact constraint box. * * When tracks are aligned with the GCell boundaries they one exactly on * the boundary can belong to the GCell on either side of the boundary. * But we want a clear and mutually exclusive ownership of each GCell * area. So, we choose that one GCell do not own the topmost and rightmost * track. And to implement it, we shrink top and right coordinates by * the amount of GCell::getTopRightShrink(), which must be less than the * track spacing. * * * \subsection secGCellDensity Saturation & Density Computation * * At any depth (i.e. layer), in the preferred routing direction, a GCell * can pass a finite length of wire. For example on an horizontal preferred * layer: \f[ WL_{max} = width(GCell) \times Htracks(GCell) \f] * Then the density, is the ratio between \f$WL_{max}\f$ and the actually * used wirelength: \f[ Wdensity(depth) = \frac{WL_{used}(depth)}{WL_{max}(depth)} \f] * Normally, the ratio musn't exceed 1.0, but the occupied wire length computation, * for now, doesn't merge overlapping wires belonging to the same net, so * the ratio may be slightly inaccurate. Thus in some pathological cases may * be greater than 1.0 whithout truly been overloaded. * * A Cell is considered as \e saturated if the overall density is above the * saturation ratio given by Session::getSaturateRatio(). * * Contact density is calculated as follow: \f[ Cont_{density} = \frac{|Contacts|}{Htracks \times Vtracks \times 4} \f] * It is a ratio over the number of actual contacts in the GCell and the maximal * number. The maximal number being the product of the number of tracks in * both direction and 4 stands for the hardwired number of layers (the depth). * * Should not be hardwired... \red{To be corrected in future versions.} * * * \subsection secGCellFeedthrough Feedthrough Computation * * The feedtrough value is an estimate is of how many complete tracks have been used * on a given layer of the GCell. It varies between zero and the number of track on the * GCell (complete saturation). As an estimate, it doesn't tell you the actual * number of free track, but how many you may expect assuming the routing is * reasonably well done. * * Computation is done as follow: * *
Wire typeEstimated Cost *
Straight wire (feedthrough) * \b 1.0 *
Beginning or ending global wire * \b 0.5 *
Local wire. * \b 1/3 *
Blockage wire * The exact percentage of the track *
* * * \subsection secGCellTrackComputation Track Computation * * The number of track that can go through a GCell in the horizontal * direction is computed as follow: \f[ Htracks = \frac{heigth(GCell)}{Vpitch} + 1 \f] * * The pitch is assumed to be the same for every layer and is hardwired * to 5.0 lambda. * * This is a bad architectural choice. The informations pertaining to * routing should be held at Kite level, not be hardwired and the pitch * should be made variable with the layer... * \red{To be corrected in future versions}. * * * \section secGCellLazyEvaluation GCell Lazy Evaluation * * To save processing time, the densities are not recomputed every time a * segment is modified (added, removed or moved). Instead a lazy evaluation * mechanism is used. Densities are recomputed each time a density is queried * \e and the lazy evaluation \e not explicitly disabled (flag NoUpdate). * * * \section secGCellSortingKey GCell Sorting Key * * In order to perform a lexicographical sort on the tuple \f$(density(depth),id)\f$ * of a GCell, a specific slave object GCell::Key is introduced. It is the * density on one specific depth, not the average density. * * * \section secGCellDesaturation GCell Desaturation / Layer Assignment * * In addition to it's geometrical and density functionality, the GCell * provides \e desaturation capabilities. Desaturation is the operation * of moving up feedthough AutoSegment from the bottom layers towards * the upper ones in order to balance the densities in the different * densities. Thoses operations provides building blocks for the layer * assignment stage which is provided by the Kabatic tool. * * Two strategies are avalaibles, moving one global AutoSegment at a * time with GCell::stepDesaturate() or, when one AutoSegment is moved * up, move up the whole net trunk with GCell::stepNetDesaturate(). * * \section secGCellImplantation GCell Implantation * * GCell derives from Hurricane::ExtensionGo to allow a graphical rendering * of the routing density. */ //! \function size_t GCell::getAllocateds (); //! \sreturn The number of allocated GCells. //! \function const Name& GCell::getStaticName (); //! \sreturn The name of the Go slice: \c "Katabatic::GCell". //! //! \see Hurricane::ExtensionGo //! \function const Name& GCell::getName () const; //! \sreturn The name of the Go slice: \c "Katabatic::GCell". //! //! \see Hurricane::ExtensionGo //! \function Box GCell::getBoundingBox () const; //! \sreturn The bounding box of the GCell, with the top right shrink applied. //! \function void GCell::translate ( const DbU::Unit&, const DbU::Unit& ); //! Required to exists as a Hurricane::Go derived class. But must never //! be used... //! \function GCellGrid* GCell::getGCellGrid () const; //! \sreturn The Grid of which GCell is part of. //! \function unsigned int GCell::getIndex () const; //! \sreturn The linear index of the GCell in the GCellGrid vector. //! //! \see GCellGrid for the meaning of the index. //! \function unsigned int GCell::getRow () const; //! \sreturn The row of the GCell in the GCellGrid. //! \function unsigned int GCell::getColumn () const; //! \sreturn The Column of the GCell in the GCellGrid. //! \function GCell* GCell::getLeft () const; //! \sreturn The left neighbor of the GCell (\c NULL if it is the leftmost GCell). //! \function GCell* GCell::getRight () const; //! \sreturn The right neighbor of the GCell (\c NULL if it is the rightmost GCell). //! \function GCell* GCell::getUp () const; //! \sreturn The top neighbor of the GCell (\c NULL if it is the topmost GCell). //! \function GCell* GCell::getDown () const; //! \sreturn The bottom neighbor of the GCell (\c NULL if it is the bottommost GCell). //! \function DbU::Unit GCell::getTopRightShrink (); //! \sreturn The amount of shrink on the top and right boundaries. //! \function unsigned int GCell::getDepth () const; //! \sreturn The depth (i.e. number of routing layers) of the GCell. //! \function bool GCell::isSaturated () const; //! \sreturn \true if at least one layer exceed a saturation of \c 1.0 (more wirelength //! that it can hold). //! \function bool GCell::isSaturated ( unsigned int depth ) const; //! \sreturn \true if the saturation ratio of layer \c depth is over the threshold defined //! for the GCells. //! \function bool GCell::isValid () const; //! \sreturn \true if all the AutoContact/AutoSegment of the GCell are valids. //! \function bool GCell::isAboveDensity ( float threshold ) const; //! \sreturn \true if the overall saturation ratio greater than \c threshold. //! \function bool GCell::hasFreeTrack ( size_t depth, float reserve ) const; //! \sreturn \true if there should be enough wire length to pass a wire completly //! trough this GCell. //! \function DbU::Unit GCell::getX () const; //! \sreturn The lower left X coordinate of the GCell box. //! \function DbU::Unit GCell::getY () const; //! \sreturn The lower left Y coordinate of the GCell box. //! \function DbU::Unit GCell::getXMax () const; //! \sreturn The upper right X coordinate of the GCell box (top right shrink applied). //! \function DbU::Unit GCell::getYMax () const; //! \sreturn The upper right Y coordinate of the GCell box (top right shrink applied). //! \function Interval GCell::getSide ( unsigned int direction ) const; //! \sreturn The interval corresponding to the side position of the GCell box, //! in \c direction. //! \function float GCell::getHCapacity () const; //! \return The number of track that can go through the GCell in the horizontal //! direction. For a detailed explanation of the computation see //! \ref secGCellTrackComputation. //! \function float GCell::getVCapacity () const; //! \return The number of track that can go through the GCell in the vertical //! direction. For a detailed explanation of the computation see //! \ref secGCellTrackComputation. //! \function float GCell::getDensity ( unsigned int flags=0 ) const; //! \sreturn The average density of the GCell, for all the depths. //! //! \ref secGCellDensity, \ref secGCellLazyEvaluation. //! \function float GCell::getCDensity ( unsigned int flags=0 ) const; //! \sreturn The density of contacts. //! //! \ref secGCellDensity, \ref secGCellLazyEvaluation. //! \function float GCell::getWDensity ( unsigned int depth, unsigned int flags=0 ) const; //! \sreturn The density of wires at \c depth. //! //! \ref secGCellDensity, \ref secGCellLazyEvaluation. //! \function DbU::Unit GCell::getBlockage ( unsigned int depth ) const; //! \sreturn The total length of blockage wire on layer at \c depth. //! \function float GCell::getFragmentation ( unsigned int depth ) const; //! \sreturn The longest free fragment size on layer \c depth (in percent). //! \function float GCell::getFeedthroughs ( unsigned int depth ) const; //! \sreturn The estimate number of \e occupied tracks on layer \c depth. //! //! \see \ref secGCellFeedthrough //! \function float GCell::getGlobalsCount ( unsigned int depth ) const; //! \sreturn The number of global wires that go completly through the GCell at layer \c depth. //! This do not includes the global wires that begins or ends in the GCell. //! \function const vector& GCell::getHSegments () const; //! \returns The vector of all horizontal AutoSegments that completly goes through the GCell. //! \function const vector& GCell::getVSegments () const; //! \returns The vector of all vertical AutoSegments that completly goes through the GCell. //! \function const vector& GCell::getContacts () const; //! \returns The vector of all AutoContacts owned by the GCell. //! \function AutoSegments GCell::getHStartSegments (); //! \returns A Collection of the horizontal AutoSegments that starts from this GCell. //! \function AutoSegments GCell::getVStartSegments (); //! \returns A Collection of the vertical AutoSegments that starts from this GCell. //! \function AutoSegments GCell::getHStopSegments (); //! \returns A Collection of the horizontal AutoSegments that stops in this GCell. //! \function AutoSegments GCell::getVStopSegments (); //! \returns A Collection of the vertical AutoSegments that stops in this GCell. //! \function AutoSegments GCell::getStartSegments ( unsigned int direction ); //! \returns A Collection of the horizontal or vertical AutoSegments that starts from this GCell //! according to \c direction. //! \function AutoSegments GCell::getStopSegments ( unsigned int direction ); //! \returns A Collection of the horizontal or vertical AutoSegments that stops in this GCell //! according to \c direction. //! \function size_t GCell::getRoutingPads ( set& rps ); //! \returns The size of the RoutingPad set. //! //! Fills the \c rps set with all the RoutingPads that appears in this GCell. //! (looks at all the anchors of the owned AutoContact) //! \function const Key& GCell::getKey () const; //! \returns The sorting key of the GCell. //! //! \see \ref secGCellSortingKey //! \function size_t GCell::checkDensity () const; //! \returns \c 1 if the GCell is saturated, 0 otherwise. //! //! Check, if the GCell is saturated, layer by layer. Issue a warning //! if that is the case. //! \function bool GCell::checkEdgeSaturation ( float threshold ) const; //! \returns \true if the Up/Right edge is over the \c threshold. //! //! Check if the number of AutoSegments crossing the Up & Right edges of the GCell //! exceed \c threshold. The \c thresold must be expressed as a percentage of //! the full capacity of the edges. The overload is computed as a whole and not //! depth by depth. //! \function void GCell::addBlockage ( unsigned int depth, DbU::Unit length ); //! Adds \c length of wire blockage to layer \c depth. //! \function void GCell::addHSegment ( AutoSegment* segment ); //! Adds \c segment to the list of horizontal feedthroughs. //! \function void GCell::addVSegment ( AutoSegment* segment ); //! Adds \c segment to the list of vertical feedthroughs. //! \function void GCell::addContact ( AutoContact* contact ); //! Adds \c contact to the list of contacts owned by this GCell. //! \function void GCell::removeHSegment ( AutoSegment* segment ); //! Removes \c segment to the list of horizontal feedthroughs. //! \function void GCell::removeVSegment ( AutoSegment* segment ); //! Removes \c segment to the list of vertical feedthroughs. //! \function void GCell::removeContact ( AutoContact* contact ); //! Removes \c contact to the list of contacts owned by this GCell. //! \function void GCell::updateContacts (); //! Force a geometry update on all the AutoContact of the GCell. //! \function size_t GCell::updateDensity (); //! \sreturn \true if the GCell is saturated. //! //! Update the various densities of the GCell. No actual computation is //! performed if the GCell is \e not invalidated. //! \function void GCell::updateKey ( unsigned int depth ); //! Update the GCell key with the new density at layer \c depth. //! //! \see \ref secGCellSortingKey. //! \function bool GCell::stepDesaturate ( unsigned int depth, set& globalNets, AutoSegment*& moved, unsigned int flags=0 ); //! \param depth The depth to desaturate. //! \param globalNets The set of Nets of which at least one segment has been moved up. //! \param moved The moved up AutoSegment. //! \param flags If KbForceMove is set, force one AutoSegment to move up, event if //! the GCell is not saturated in the relevant depth. //! //! \sreturn \true if an AutoSegment has actually been moved up. //! //! Perform the atomic desaturation, that is move up one AutoSegment from //! layer \c depth to layer depth+2, longuests AutoSegments are //! moved first. Only global feedthrough AutoSegments are candidates to be //! moved up. The Net owning the moved up segment is added to the \c globalNets //! set. If the GCell is not saturated on layer \c depth, nothing is //! done. If the \c forced flag is set, one global AutoSegment is moved up //! regardless of the saturation status. //! //! \see \ref secGCellDesaturation //! \function bool GCell::stepNetDesaturate ( unsigned int depth, set& globalNets, SetIndex& invalidateds ); //! \param depth The depth to desaturate. //! \param globalNets The set of Nets of which at least one segment has been moved up. //! \param invalidateds The set of GCell ids that have been invalidateds. //! //! \sreturn \true if a Net has been moved up. //! //! Perform a desaturation by whole Net trunk. Select the longest feedthrough //! AutoSegment in layer \c depth, then attempt to move up the whole Net (all //! it's global AutoSegments are moved up). //! //! \see \ref secGCellDesaturation //! \function bool GCell::rpDesaturate ( set& nets ); //! If the number of RoutingPad in the first routing layer exceed the //! Session::getSaturateRp() threshold, force a desaturation of layer //! \c depth 1 until it is below 0.5. //! //! \see \ref secGCellDesaturation /*! \class GCell::CompareByIndex * * \brief GCell Index Comparison Functor * * A comparison functor for GCell, compare by \c index (the linear * index in the GCellGrid vector. */ //! \typedef typedef set GCell::SetIndex; //! Shorthand for a set of GCell sorted on their index. /*! \class GCell::CompareByDensity * * \brief GCell Density Comparison Functor * * A comparison functor for GCell, compare by density on layer \c depth. */ //! \function GCell::CompareByDensity::CompareByDensity ( unsigned int depth ); //! Build a density comparator for GCells on layer \c depth. /*! \class GCell::Key * * \brief GCell Key - Density Cache * * This class is used to create a GCell internal cache on density, mainly * to be used by GCellDensitySet. */ //! \function GCell::Key::Key ( GCell* owner, unsigned int depth ); //! \param owner The GCell owning the key. //! \param depth The layer \c depth of the density to use. //! //! Key constructor, with an initial value for the cached density. //! \function GCell* GCell::Key::getGCell () const; //! \sreturn The owning GCell. //! \function float GCell::Key::getDensity () const; //! \sreturn The value of the cached density. //! \function void GCell::Key::update ( unsigned int depth ); //! \sreturn Update the density /*! \class GCellDensitySet * * \brief GCell Set, sorted by density * * A small container helper to manage a set of GCell sorted by density * on a specific layer \c depth. * * The helper is implemented in term of a set. Once inserted in a set * an element must not have is sorting key changed. But GCell density * may change due to AutoSegment modifications during the lifetime of * the set. To circumvent this problem, the GCell provide a key attribute * to be used specifically with GCellDensitySet. This key act as a cached * copy of the GCell density which is updated \e only by a call to * GCell::updateKey() (and \e not GCell::updateDensity()). GCell which * density have changed and key has to be updated must be signaled to * set with the GCellDensityQueue::unqueue() method. When we want to * update the sorting of the set on the new densities, we call * GCellDensitySet::requeue() which, for each invalidated GCell do: * - Remove the GCell from the set. * - Update the key (call GCell::updateKey()). * - Reinsert the GCell in the set (thus with the updated key). * * Typical usage: \code GCellDensitySet gcells ( 2, *(getGCellGrid()->getGCellVector()) ); while ( true ) { bool optimized = false; std::set::const_iterator igcell = gcells.getGCells().begin(); for ( ; igcell != gcells.getGCells().end() ; ++igcell ) { if ( doSomeOptimization(*igcell) ) { optimized = true; gcells.unqueue( *igcell ); } } if (not optimized) break; gcells.requeue(); } \endcode * */ //! \function GCellDensitySet::GCellDensitySet ( unsigned int depth ); //! Create a new empty GCellDensitySet, sorting on density of layer \c depth. //! \function GCellDensitySet::GCellDensitySet ( unsigned int depth, const std::vector& gcells ); //! Create a new empty GCellDensitySet, sorting on density of layer \c depth. //! Load the queue with the GCells supplied in the \c gcells vector. //! \function GCellDensitySet::~GCellDensitySet (); //! Delete a GCellDensitySet, if the queue is not empty, issue a warning. //! \function bool GCellDensitySet::empty () const; //! \sreturn \true if the queue is empty. //! \function size_t GCellDensitySet::size () const; //! \sreturn the numbers of elements in the queue. //! \function const std::set& GCellDensitySet::getGCells () const; //! \sreturn the list of GCells currently in the queue. //! \function size_t GCellDensitySet::insert ( GCell* gcell ); //! Insert \c gcell into the set. //! \function size_t GCellDensitySet::erase ( GCell* gcell ); //! Remove \c gcell from the set. //! \function void GCellDensitySet::unqueue ( GCell* gcell ); //! Invalidate \c gcell. The density of \c gcell may have changed and needs to be //! reinserted into the queue. It is temporarily set asides until the next //! call to GCellDensitySet::requeue(). //! \function void GCellDensitySet::requeue (); //! Reinsert in the queue all the GCells that have been previously //! invalidated by a call to GCellDensitySet::unqueue(). This function calls //! GCell::updateKey() before reinserting the GCell. }