
// -*- C++ -*-
  
namespace Anabatic {

/*! \defgroup     LoadGlobalRouting  Global Routing Loading
 *  \brief        Translation rules to build detailed routing from global
 *
 *                This module documents how the global routing built by \c Knik is
 *                loaded into the \c Anabatic data-base. It is intented for developpers
 *                only.
 */

//! \addtogroup   LoadGlobalRouting
//! \{

//! \enum         LocalFunctionFlag
//!               A set of flags for all functions of the LoadGlobalRouting module.
//!               They can be combined to form the \e flags argument of functions.
//!               the functions will ignore flags that are not intended to them.
//!
//!               For \c HSmall, \c VSmall & \c Punctual see checkRoutingPadSize().

//! \var          LocalFunctionFlag::NoFlags
//!               A simple alias over zero to explicitly tell that no flag at all is
//!               passed to the function.

//! \var          LocalFunctionFlag::HAccess
//!               The constructed topology will be accessed through an horizontal
//!               segment. The absence of this flag tell that the access will be done
//!               trough a vertical.

//! \var          LocalFunctionFlag::VSmall
//!               The RoutingPad vertically covers a very small number of access points,
//!               so it is likely overconstrained for direct horizontal connexion.

//! \var          LocalFunctionFlag::HSmall
//!               The RoutingPad horizontally covers a very small number of access points,
//!               so it is likely overconstrained for direct vertical connexion.

//! \var          LocalFunctionFlag::Punctual
//!               The RoutingPad covers only an access point in either direction.

//! \var          LocalFunctionFlag::DoSourceContact
//!               When creating Anabatic::AutoContactTerminal on non-punctual RoutingPad, this flag
//!               request the creation of a contact <em>on the source point</em>.

//! \var          LocalFunctionFlag::DoTargetContact
//!               When creating Anabatic::AutoContactTerminal on non-punctual RoutingPad, this flag
//!               request the creation of a contact <em>on the target point</em>.


//! \function     uint64_t  checkRoutingPadSize ( Component* rp );
//!
//!               Look at the geometrical size of the Component and assess if
//!               it's span is too narrow either horizontally or vertically.
//!               Return a combination of flags indicating it's state:
//!                 - HSmall : less than 3 pitches in horizontal direction.
//!                 - VSmall : less than 3 pitches in vertical direction.
//!                 - Punctual : one pitch in either directions.
//!
//!               The component can be a RoutingPad, a Vertical or an Horizontal.
//!
//!               \image html  checkRoutingPadSize.png "checkRoutingPadSize()"

/*! \class        NetBuilder
 *
 *  \brief        Build the wiring for a Net inside a GCell (\b internal).
 *
 *                As this class is called to initially construct the Anabatic wiring,
 *                it must build a \b connex wiring. That is without gaps in layer depth,
 *                because the topology restauration mechanism (AutoContact::updateTopology())
 *                of the AutoContact cannot work until all AutoSegments are revalidated at
 *                least once. The topology restauration work by creating doglegs which in turn,
 *                call the canonization, which needs all the caches to be up to date.
 */

//! \function     void  NetBuilder::doRp_AutoContacts ( GCell* gcell, Component* rp, AutoContact*& source, AutoContact*& target, uint64_t flags );
//! \param        gcell   The GCell into which create the AutoContact.
//! \param        rp      The Component we want to access.
//! \param        source  The AutoContact created on the \c source (\e returned).
//! \param        target  The AutoContact created on the \c target (\e returned).
//! \param        flags   Managed by this function:
//!                         - LocalFunctionFlag::DoSourceContact
//!                         - LocalFunctionFlag::DoTargetContact
//!
//!               Create the AutoContact directly anchored on the Component (terminal).
//!               Three cases are manageds:
//!                 -# <b>Ordinary (non-punctual) \c METAL1 terminal</b>: an AutoContactTerminal
//!                    is anchored on the RoutingPad.
//!                 -# <b>Punctual \c METAL1 terminal</b>, the access must never be blocked
//!                    by other routing. To ensure it, we create a fixed AutoSegment (anchored
//!                    on two AutoContactTerminal) to cover it. The \e normal AutoContactTerminal
//!                    is also created.
//!                 -# <b>non \c METAL1 terminal</b>, as for the punctual \c METAL1, a
//!                    fixed protection is added over the RoutingPad. If we access
//!                    horizontally a vertical RoutingPad or vertically an horizontal
//!                    one, an extra AutoContactTerminal is added (to allow is displacement
//!                    along the RoutingPad).
//!
//!               To avoid creating a fixed protection over a RoutingPad multiple times,
//!               the RoutingPad and it's associated protection is stored in a static
//!               \c map : \c __routingPadAutoSegments.
//!
//!               Conversely, because an AutoContactTerminal can only be connected to one
//!               segment, each time this function is called a new terminal will be created
//!               (or maybe two in case of non-punctual terminals). If only one AutoContact
//!               is requested, it is created centered on the RoutingPad. The initial
//!               position of AutoContact <em>do not prevent them to move afterwards</em>,
//!               even those created on source/target on a non-punctual RoutingPad.
//!
//! \remark       For clarity we describe the layer management of this function in term
//!               of \c METAL, but it is the RoutingGauge depth which is actually used.
//!
//!               \image html  doRp_AutoContacts.png "doRp_AutoContacts()"

//! \function     AutoContact* NetBuilder::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags );
//! \param        gcell   The GCell into which create the AutoContact.
//! \param        rp      The Component onto which anchor the access contact.
//! \param        flags   Relevant flags are:
//!                         - HAccess, the terminal is to be accessed through an horizontal
//!                           segment.
//!                         - VSmall, force the terminal to be considered as small in the
//!                           vertical direction.
//!
//!               If \c HAccess is set, the Component is to be accessed trough an horizontal
//!               segment. If unset, the access is done vertically.
//!
//!               Create an AutoContact to access a Component (terminal). If the Component
//!               is not to be accessed through an horizontal segment, and do not cover a
//!               large span in the horizontal direction (flag \c VSmall), a local horizontal
//!               AutoSegment is added to slacken the vertical constraints.
//!
//!               \image html  doRp_Access.png "doRp_Access()"

//! \function     AutoContact*  NetBuilder::doRp_AccessPad ( RoutingPad* rp, uint64_t flags );
//! \param        rp      The Component onto which anchor the access contact.
//! \param        flags   Relevant flags are:
//!                         - HAccess, the terminal is to be accessed through an horizontal
//!                           segment.
//!                         - VSmall, force the terminal to be considered as small in the
//!                           vertical direction.
//! \return       A Anabatic::AutoContactTerminal .
//!
//!               The Component \c rp is a RoutingPad which belongs to a pad cell. This case
//!               occurs when we are routing a complete chip. This method build, from the
//!               \c rp a stack of articulated punctual segments and contacts to reach the
//!               default H/V routing layers (usually \c METAL2 & \c METAL3). This may be
//!               needed when the pad terminal is in \c METAL5, for instance.
//!
//!               The returned AutoContactTerminal is anchored on the last punctual segment
//!               build.
//!
//!               The GCell into which the AutoContactTerminal is created may be under the
//!               pads area. However, it will be right on the border of the GCell.
//!               The global router vertexes of GCell under the pad area are marked as
//!               blocked so will never be used for routing.
//!
//! \remark       The segments and contacts added to ensure the layer connexity are not
//!               put into the Anabatic database. They are plain Hurricane objects, invisibles
//!               from it.

//! \function     void  NetBuilder::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 );
//!
//!               Build the wiring to connect to horizontal Component. Two cases:
//!                 - The Component are aligneds, then only a straight wire is created.
//!                 - They are \e not aligned, then a complete dogleg is created.
//!
//!               \image html  doRp_StairCaseH.png "doRp_StairCaseH()"

//! \function     void  NetBuilder::doRp_StairCaseV ( GCell* gcell, Component* rp1, Component* rp2 );
//!
//!               Build the wiring to connect to vertical Components. Two cases:
//!                 - The Components are aligneds, then only a straight wire is created.
//!                 - They are \e not aligned, then a complete dogleg is created.
//!
//!               \image html  doRp_StairCaseV.png "doRp_StairCaseV()"

//! \function     void  NetBuilder::_do_xG_1Pad ();
//!
//!               Construct the topology, when there is only global wires and one local
//!               terminal, but coming from a Pad. As thoses connectors will always be
//!               on one border of the GCell they can be considered as a kind of global.
//!
//!               So this method mostly calls NetBuilder::doRp_AccessPad() to create
//!               the AutoContactTerminal, then calls NetBuilder::_do_xG(), except
//!               for straight lines which are managed directly.

//! \function     void  NetBuilder::_do_xG ();
//!
//!               Construct the topology, when there is only global wires (no local terminals).
//!               
//!               Some topology are not handled because they must not be managed by this
//!               function:
//!               <ul>
//!                 <li>One global: nonsensical because there also must be a terminal.
//!                 <li>Two aligned globals: in that case we do a straight wire whithout
//!                     any AutoContact (handled by the source/target of the wire).
//!               </ul>
//!
//!               \image html  _do_xG.png "_do_xG()"

//! \function     void  NetBuilder::_do_1G_1M1 ();
//!
//!               Construct a topology where there is \e one global and one RoutingPad
//!               in \c METAL1. The \c METAL1 is assumed to be vertical.
//!
//! \remark       When accessing the RoutingPad through an horizontal global segment
//!               and the vertical extension of the segment is small, the global is
//!               still directly attached to the terminal, inducing a high constraint
//!               on it. We left to job of slackening it to the router.
//!
//!               \image html  _do_1G_1M1.png "_do_1G_1M1()"

//! \function     void  NetBuilder::_do_1G_xM1 ();
//!
//!               Construct a topology where there is \e one global and any number of
//!               RoutingPad in \c METAL1. The \c METAL1 is assumed to be vertical.
//!
//!               The RoutingPads are linked together two by two. If the horizontal
//!               segments are not aligned by the router, part of the routage will be
//!               done through the RoutingPad itself. The global incoming segment will
//!               connected to the leftmost, rightmost or centermost RoutingPad according
//!               from wich side it comes from.
//!
//!               \image html  _do_1G_xM1.png "_do_1G_xM1()"

//! \function     void  NetBuilder::_do_xG_1M1_1M2 ();
//!
//!               Construct a topology where there is at least one global (and up to 4),
//!               one \c METAL1 RoutingPad (assumed V) and one \c METAL2 RoutingPad (assumed H).
//!
//!               In this topology, we want to try to reuse the \c METAL2 RoutingPad as a
//!               feedtrough in the horizontal routage. Thus:
//!                 - The \c METAL1 and \c METAL2 RoutingPad are connected through a separate wiring.
//!                 - The south & west global wiring is attached to the leftmost contact of
//!                   the \c METAL2.
//!                 - The north & east global wiring is attached to the rightmost contact of
//!                   the \c METAL2.
//!
//!               South/west and north/south can be build independantly. Depending on the number
//!               of globals, they can consist of:
//!                 - Nothing (no south nor west).
//!                 - An AutoContact (west present).
//!                 - An horizontal plus a turn (south present).
//!                 - An horizontal plus a HTee (south & west present).
//!
//! \remark       Not all configurations are represented below.
//!
//!               \image html  _do_xG_1M1_1M2.png "_do_xG_1M1_1M2()"

//! \function     void  NetBuilder::_do_xG_xM1_xM3 ();
//!
//!               Construct a topology where there is at least one global (and up to 4),
//!               at least one \c METAL1 RoutingPad (assumed V) and at least one \c METAL3
//!               RoutingPad (assumed V).
//!
//!               In this topology, we want to try to reuse the \c METAL3 RoutingPad as a
//!               feedtrough in the vertical routage. Thus:
//!                 - The \c METAL1 and \c METAL3 RoutingPad are connected through a separate
//!                   wiring made of separate horizontals.
//!                 - The south-west global wiring is attached to the leftmost RoutingPad
//!                   if there isn't south or to the first \c METAL3 otherwise.
//!                 - The north-east global wiring is attached to the rightmost RoutingPad
//!                   if there isn't north or to the first \c METAL3 otherwise.
//!
//!               South/west and north/south can be build independantly. Depending on the number
//!               of globals, they can consist of:
//!                 - Nothing (no south nor west).
//!                 - An AutoContact on the leftmost RoutingPad (west present).
//!                 - An AutoContact on the first \c METAL3 (only south present).
//!                 - An AutoContact plus a vertical plus a VTee (south & west present).
//!
//!               \image html  _do_xG_xM1_xM3.png "_do_xG_xM1_xM3()"

//! \function     void  NetBuilder::_do_xG_xM2 ();
//!
//!               Construct a topology where there is at least one global (and up to 4),
//!               and any number of \c METAL2 RoutingPads (assumeds H).
//!
//!               In this topology, we want to try to reuse the \c METAL2 RoutingPad as a
//!               feedtrough in the horizontal routage. Thus:
//!                 - The RoutingPad are connecteds trough a separate staircase (or
//!                   straight wire if aligneds).
//!                 - The south-west global wiring is attached to the leftmost RoutingPad
//!                   if there isn't south or to the biggest horizontal RoutingPad otherwise.
//!                 - The north-east global wiring is attached to the rightmost RoutingPad
//!                   if there isn't south or to the biggest horizontal RoutingPad otherwise.
//!
//!               \image html  _do_xG_xM2.png "_do_xG_xM2()"

//! \function     void  NetBuilder::_do_1G_1M3 ();
//!
//!               Construct a topology where there is one global and one \c METAL3 RoutingPad
//!               (assumeds V).
//!
//!               In this topology, we reuse the \c METAL3 RoutingPad as a feedtrough in the
//!               vertical routage. Thus:
//!                 - If the global is either north or south, we directly connect to the
//!                   north end or south end of the RoutingPad. \red{The vertical global will}
//!                   \red{have no slack at all we assume that METAL3 terminals are only from}
//!                   \red{blocks and are aligneds vertically.}
//!                 - If the global is east or west \e and the RoutingPad is sufficiently
//!                   extended in the vertical direction, we connect an horizontal in the
//!                   normal way.
//!                 - If the global is not sufficiently extended, we add a turn to give some
//!                   slack to the global.
//!
//!
//!               \image html  _do_1G_1M3.png "_do_1G_1M3()"

//! \function     void  NetBuilder::_do_xG_xM3 ();
//!
//!               Construct a topology where there at least one global and two \c METAL3 RoutingPad
//!               (assumed V).
//!
//!               In this topology, we reuse the \c METAL3 RoutingPad as a feedtrough in the
//!               vertical routage. \red{We assume that the most likely relative position}
//!               \red{of the RoutingPads is to be aligned vertically}.
//!               Thus:
//!                 - All RoutingPads are linked two by two trough vertical staircases.
//!                 - The south-west global wiring is attached to the bottommost RoutingPad
//!                   (without vertical slack). If a misalignment is detected, then a
//!                   dogleg is added.
//!                 - The north-east global wiring is attached to the topmost RoutingPad
//!                   (without vertical slack).
//!
//!               South/west and north/south can be build independantly. Depending on the number
//!               of globals, they can consist of:
//!                 - Nothing (no south nor west).
//!                 - An sliding AutoContact on the bottommost RoutingPad (west present).
//!                 - An fixed AutoContact on the bottommost RoutingPad (only south present).
//!                 - An fixed AutoContact plus a vertical plus a VTee (south & west present).
//!
//!               \image html  _do_xG_xM3.png "_do_xG_xM3()"

//! \function     void  singleGCell ( AnabaticEngine* anbt, Net* net );
//!
//!               All the RoutingPads of the net are concentrated under a single
//!               GCell. This function assumes that all the terminals are in
//!               \c METAL1 (vertical), and link them two by two by horizontal
//!               wires.

//! \}

}
