coriolis/katabatic/src/LoadGrByNet.cpp

1925 lines
78 KiB
C++
Raw Normal View History

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
// Copyright (c) UPMC 2008-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | K a t a b a t i c - Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./LoadGrByNet.cpp" |
// +-----------------------------------------------------------------+
#include <cstdlib>
#include <sstream>
#include "hurricane/Bug.h"
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DebugSession.h"
#include "hurricane/Layer.h"
#include "hurricane/Technology.h"
#include "hurricane/DataBase.h"
#include "hurricane/Net.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/RoutingPads.h"
#include "hurricane/Pad.h"
#include "hurricane/Plug.h"
#include "hurricane/Cell.h"
#include "hurricane/Instance.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/Measures.h"
#include "katabatic/AutoContactTerminal.h"
#include "katabatic/AutoContactTurn.h"
#include "katabatic/AutoContactHTee.h"
#include "katabatic/AutoContactVTee.h"
#include "katabatic/AutoSegment.h"
#include "katabatic/GCellGrid.h"
#include "katabatic/KatabaticEngine.h"
namespace {
/*! \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 Katabatic data-base. It is intented for developpers
* only.
*/
//! \addtogroup LoadGlobalRouting
//! \{
//! \enum LocalFunctionFlag
//! A set of flags for all functions of the LoadGrByNet 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 Katabatic::AutoContactTerminal on non-punctual RoutingPad, this flag
//! request the creation of a contact <em>on the source point</em>.
//! \var LocalFunctionFlag::DoTargetContact
//! When creating Katabatic::AutoContactTerminal on non-punctual RoutingPad, this flag
//! request the creation of a contact <em>on the target point</em>.
//! \function unsigned int 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 GCellTopology
*
* \brief Build the wiring for a Net inside a GCell (\b internal).
*
*/
//! \function void GCellTopology::doRp_AutoContacts ( GCell* gcell, Component* rp, AutoContact*& source, AutoContact*& target, unsigned int 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* GCellTopology::doRp_Access ( GCell* gcell, Component* rp, unsigned int 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 void GCellTopology::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 GCellTopology::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 GCellTopology::_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 GCellTopology::_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 GCellTopology::_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 GCellTopology::_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 GCellTopology::_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 GCellTopology::_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 GCellTopology::_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 GCellTopology::_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 ( KatabaticEngine* ktbt, 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.
//! \}
using namespace std;
using namespace CRL;
using namespace Hurricane;
using namespace Katabatic;
// ---------------------------------------------------------------
// Local Enum/Types.
enum LocalFunctionFlag { NoFlags = 0x00000000
, SortDecreasing = 0x00000001
, HAccess = 0x00000002
, VSmall = 0x00000004
, HSmall = 0x00000008
, Punctual = 0x00000010
, HCollapse = 0x00000020
, VCollapse = 0x00000040
, Terminal = 0x00000080
, DoSourceContact = 0x00000100
, DoTargetContact = 0x00000200
, SouthBound = 0x00010000
, NorthBound = 0x00020000
, WestBound = 0x00040000
, EastBound = 0x00080000
};
// ---------------------------------------------------------------
// Local Variables.
const char* invalidGCell =
"Katabatic::GCellTopology () :\n\n"
" No GCell under point.\n";
const char* mismatchGCell =
"Katabatic::GCellTopology () :\n\n"
" Contacts under two different GCells.\n";
const char* missingGCell =
"Katabatic::GCellTopology () :\n\n"
" No Contact in GCell.\n";
map<Component*,AutoSegment*> __routingPadAutoSegments;
// ---------------------------------------------------------------
// LoadGrByNet Local Classes.
struct NetCompareByName {
inline bool operator() ( const Net* lhs, const Net* rhs ) const;
};
inline bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const
{ return lhs->getName() < rhs->getName(); }
// ---------------------------------------------------------------
// LoadGrByNet Local Functions.
void lookupClear ()
{ __routingPadAutoSegments.clear (); }
void getPositions ( Component* anchor, Point& source, Point& target )
{
Segment* segment = dynamic_cast<Segment*>( anchor );
if (segment) {
source = segment->getSourcePosition();
target = segment->getTargetPosition();
return;
}
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
if (rp) {
source = rp->getSourcePosition();
target = rp->getTargetPosition();
return;
}
source = anchor->getPosition();
target = anchor->getPosition();
}
unsigned int checkRoutingPadSize ( Component* anchor )
{
Point source;
Point target;
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
size_t anchorDepth = Session::getLayerDepth( anchor->getLayer() );
if (anchorDepth == 0) ++anchorDepth;
getPositions( anchor, source, target );
DbU::Unit width = abs( target.getX() - source.getX() );
DbU::Unit height = abs( target.getY() - source.getY() );
unsigned int flags = 0;
// HARDCODED VALUE.
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
flags |= (width < 3*Session::getPitch(anchorDepth)) ? HSmall : 0;
flags |= (height < 3*Session::getPitch(anchorDepth)) ? VSmall : 0;
flags |= ((width == 0) && (height == 0)) ? Punctual : 0;
return flags;
}
Hook* getSegmentOppositeHook ( Hook* hook )
{
Segment* segment = static_cast<Segment*>( hook->getComponent() );
return segment->getOppositeHook( hook );
}
unsigned int getSegmentHookType ( Hook* hook )
{
Horizontal* horizontal = dynamic_cast<Horizontal*>( hook->getComponent() );
if (horizontal) {
if (horizontal->getSourceX() > horizontal->getTargetX())
cerr << Warning("Bad orientation of %s",getString(horizontal).c_str()) << endl;
if (dynamic_cast<Segment::SourceHook*>(hook))
return EastBound;
return WestBound;
} else {
Vertical* vertical = dynamic_cast<Vertical*>( hook->getComponent() );
if (vertical) {
if (vertical->getSourceY() > vertical->getTargetY())
cerr << Warning("Bad orientation of %s",getString(vertical).c_str()) << endl;
if (dynamic_cast<Segment::SourceHook*>(hook))
return NorthBound;
} else {
cerr << Warning("Unmanaged Hook %s",getString(hook).c_str()) << endl;
}
}
return SouthBound;
}
// ---------------------------------------------------------------
// Class : "SortRpByX".
class SortRpByX {
public:
inline SortRpByX ( unsigned int flags );
inline bool operator() ( Component* rp1, Component* rp2 );
protected:
unsigned int _flags;
};
inline SortRpByX::SortRpByX ( unsigned int flags )
: _flags(flags)
{ }
inline bool SortRpByX::operator() ( Component* rp1, Component* rp2 )
{
DbU::Unit x1 = rp1->getCenter().getX();
DbU::Unit x2 = rp2->getCenter().getX();
if (x1 == x2) return false;
return (_flags & SortDecreasing) xor (x1 < x2);
}
// ---------------------------------------------------------------
// Class : "SortRpByY".
class SortRpByY {
public:
inline SortRpByY ( unsigned int flags );
inline bool operator() ( Component* rp1, Component* rp2 );
protected:
unsigned int _flags;
};
inline SortRpByY::SortRpByY ( unsigned int flags )
: _flags(flags)
{ }
inline bool SortRpByY::operator() ( Component* rp1, Component* rp2 )
{
DbU::Unit y1 = rp1->getCenter().getY();
DbU::Unit y2 = rp2->getCenter().getY();
if (y1 == y2) return false;
return (_flags & SortDecreasing) xor (y1 < y2);
}
// ---------------------------------------------------------------
// Class : "ForkStack".
class ForkStack {
public:
inline void push ( Hook* from, AutoContact* contact );
inline void pop ();
inline Hook* getFrom () const;
inline AutoContact* getContact () const;
private:
struct Element {
Hook* _from;
AutoContact* _contact;
inline Element ( Hook* from, AutoContact* contact );
};
private:
list<Element> _stack;
};
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact ) : _from(from), _contact(contact) {}
inline void ForkStack::pop () { if (not _stack.empty()) _stack.pop_back(); }
inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; }
inline AutoContact* ForkStack::getContact () const { return _stack.empty() ? NULL : _stack.back()._contact; }
inline void ForkStack::push ( Hook* from, AutoContact* contact )
{
ltrace(80) << " Stacking " << from << " + " << contact << endl;
_stack.push_back( Element(from,contact) );
}
// ---------------------------------------------------------------
// Class : "GGellTopology".
class GCellTopology {
public:
static void init ( unsigned int degree );
static void fixSegments ();
GCellTopology ( GCellGrid*, Hook* fromHook, AutoContact* sourceContact=NULL );
void construct ( ForkStack& forks );
inline unsigned int getStateG () const;
inline GCell* getGCell () const;
static void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, unsigned int flags );
static AutoContact* doRp_Access ( GCell*, Component*, unsigned int flags );
static void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 );
static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 );
private:
void _do_xG ();
void _do_xG_1Pad ();
void _do_1G_1PinM2 ();
void _do_1G_1M1 ();
void _do_1G_xM1 ();
void _do_xG_xM1_xM3 ();
void _do_xG_1M1_1M2 ();
void _do_xG_xM2 ();
void _do_1G_1M3 ();
void _do_xG_xM3 ();
private:
enum ConnexityBits { GlobalBSize = 3
, Metal1BSize = 3
, Metal2BSize = 3
, Metal3BSize = 3
, PadsBSize = 3
, PinsBSize = 3
};
#define CONNEXITY_VALUE( Gs, M1s, M2s, M3s, pads, pins ) \
Gs + ((M1s ) << GlobalBSize) \
+ ((M2s ) << (GlobalBSize+Metal1BSize)) \
+ ((M3s ) << (GlobalBSize+Metal1BSize+Metal2BSize)) \
+ ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \
+ ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize))
// Connexity Name | G|M1|M2|M2|Pad|Pin|
enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 )
, Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 )
, Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 )
, Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 )
, Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 )
, Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 )
, Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 )
, Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 )
, Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 )
, Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 )
, Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 )
, Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 )
, Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 )
, Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 )
, Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 )
, Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 )
, Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 )
, Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 )
, Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 )
// Connexity Name | G|M1|M2|M2|Pad|Pin|
, Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 )
, Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 )
, Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 )
, Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 )
, Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 )
, Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 )
, Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 )
, Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 )
, Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 )
, Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 )
, Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 )
, Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 )
, Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 )
// Connexity Name | G|M1|M2|M2|Pad|Pin|
, Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 )
, Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 )
, Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 )
, Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 )
, Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 )
, Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 )
, Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 )
, Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 )
, Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 )
// Connexity Name | G|M1|M2|M2|Pad|Pin|
, Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 )
, Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 )
, Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 )
, Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 )
, Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 )
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
};
// Connexity Union Type.
union UConnexity {
unsigned int connexity;
struct {
unsigned int globals : GlobalBSize;
unsigned int M1 : Metal1BSize;
unsigned int M2 : Metal2BSize;
unsigned int M3 : Metal3BSize;
unsigned int Pad : PadsBSize;
unsigned int Pin : PinsBSize;
} fields;
};
enum TopologyFlag { Global_Vertical_End = 0x00000001
, Global_Horizontal_End = 0x00000002
, Global_Horizontal = 0x00000004
, Global_Vertical = 0x00000008
, Global_Turn = 0x00000010
, Global_Fork = 0x00000020
, Global_Fixed = 0x00000040
, Global_End = Global_Vertical_End | Global_Horizontal_End
, Global_Split = Global_Horizontal | Global_Vertical | Global_Fork
};
// Attributes.
private:
static vector<AutoSegment*> _toFixSegments;
static unsigned int _degree;
UConnexity _connexity;
unsigned int _topology;
Net* _net;
GCell* _gcell;
AutoContact* _sourceContact;
AutoContact* _southWestContact;
AutoContact* _northEastContact;
Hook* _fromHook;
Hook* _east;
Hook* _west;
Hook* _north;
Hook* _south;
vector<Component*> _routingPads;
};
inline unsigned int GCellTopology::getStateG () const { return _connexity.fields.globals; }
inline GCell* GCellTopology::getGCell () const { return _gcell; }
vector<AutoSegment*> GCellTopology::_toFixSegments;
unsigned int GCellTopology::_degree = 0;
void GCellTopology::fixSegments ()
{
for ( size_t i=0 ; i<_toFixSegments.size() ; ++i )
_toFixSegments[i]->setFlags( SegFixed );
_toFixSegments.clear();
}
void GCellTopology::init ( unsigned int degree )
{
_degree = degree;
_toFixSegments.clear();
}
GCellTopology::GCellTopology ( GCellGrid* gcellGrid
, Hook* fromHook
, AutoContact* sourceContact )
: _connexity ()
, _topology (0)
, _gcell (NULL)
, _sourceContact (sourceContact)
, _southWestContact(NULL)
, _northEastContact(NULL)
, _fromHook (fromHook)
, _east (NULL)
, _west (NULL)
, _north (NULL)
, _south (NULL)
, _routingPads ()
{
_connexity.connexity = 0;
ltrace(99) << "GCellTopology::GCellTopology()" << endl;
ltracein(99);
ltrace(99) << getString(fromHook) << endl;
ltrace(99) << sourceContact << endl;
Segment* fromSegment = static_cast<Segment*>( _fromHook->getComponent() );
_net = fromSegment->getNet();
forEach ( Hook*, hook, fromHook->getHooks() ) {
Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() );
if (toSegment) {
switch ( getSegmentHookType(*hook) ) {
case WestBound: _west = *hook; break;
case EastBound: _east = *hook; break;
case SouthBound: _south = *hook; break;
case NorthBound: _north = *hook; break;
}
_connexity.fields.globals++;
} else {
Component* anchor = hook->getComponent();
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
ltrace(99) << "| Looking for Anchor:" << anchor << " rp:" << rp << endl;
if (anchor) {
Contact* contact = dynamic_cast<Contact*>( anchor );
if (contact
and ( Session::getKatabatic()->isGContact( anchor->getLayer() )
or Session::getKatabatic()->isGMetal ( anchor->getLayer() )) ) {
// Global routing articulation contact are in <gmetalh> not <gcut> ?
GCell* gcell = gcellGrid->getGCell( contact->getCenter() );
ltrace(99) << "* Global Routing Articulation: " << contact << endl;
ltrace(99) << "| " << gcell << endl;
if (gcell == NULL)
throw Error( invalidGCell );
if (_gcell == NULL) _gcell = gcell;
else if (_gcell != gcell) {
throw Error( mismatchGCell );
}
} else {
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAsComponent()->getCell())) {
_connexity.fields.Pad++;
} else {
const Layer* layer = anchor->getLayer();
if (layer == Session::getRoutingLayer(0)) _connexity.fields.M1++; // M1 V
else if (layer == Session::getRoutingLayer(1)) _connexity.fields.M2++; // M2 H
else if (layer == Session::getRoutingLayer(2)) _connexity.fields.M3++; // M3 V
else if (layer == Session::getRoutingLayer(3)) _connexity.fields.M2++; // M4 H
else if (layer == Session::getRoutingLayer(4)) _connexity.fields.M3++; // M5 V
else {
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
, getString(layer->getName()).c_str()
, getString(anchor).c_str() )
<< endl;
continue;
}
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) _connexity.fields.Pin++;
}
ltrace(99) << "| Component to connect: " << anchor << endl;
_routingPads.push_back( anchor );
}
}
}
}
ltrace(99) << "east: " << _east << endl;
ltrace(99) << "west: " << _west << endl;
ltrace(99) << "north:" << _north << endl;
ltrace(99) << "south:" << _south << endl;
if (_connexity.fields.globals == 1) {
if ( _north or _south ) _topology |= Global_Vertical_End;
else _topology |= Global_Horizontal_End;
} else if (_connexity.fields.globals == 2) {
if ( _east && _west ) _topology |= Global_Horizontal;
else if ( _north && _south ) _topology |= Global_Vertical;
else _topology |= Global_Turn;
} else {
_topology |= Global_Fork;
}
ltraceout(99);
if (_gcell == NULL) throw Error( missingGCell );
}
void GCellTopology::construct ( ForkStack& forks )
{
ltrace(99) << "GCellTopology::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
ltracein(99);
_southWestContact = NULL;
_northEastContact = NULL;
bool straightLine = false;
switch ( _connexity.connexity ) {
case Conn_1G_1Pad:
case Conn_2G_1Pad:
case Conn_3G_1Pad: _do_xG_1Pad(); break;
case Conn_1G_1PinM2: _do_1G_1PinM2(); break;
case Conn_1G_1M1: _do_1G_1M1(); break;
case Conn_1G_2M1:
case Conn_1G_3M1:
case Conn_1G_4M1: _do_1G_xM1(); break;
case Conn_1G_1M2:
case Conn_1G_2M2:
case Conn_1G_3M2:
case Conn_1G_4M2: _do_xG_xM2(); break;
case Conn_1G_1M3: _do_1G_1M3(); break;
case Conn_1G_2M3:
case Conn_1G_3M3:
case Conn_1G_4M3: _do_xG_xM3 (); break;
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break;
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
case Conn_2G_1M1:
case Conn_2G_2M1:
case Conn_2G_3M1:
case Conn_2G_4M1:
case Conn_3G_1M1:
case Conn_3G_2M1:
case Conn_3G_3M1:
case Conn_3G_4M1:
case Conn_3G_2M3:
case Conn_3G_3M3:
case Conn_3G_4M3:
case Conn_4G_1M1:
case Conn_4G_2M1:
case Conn_4G_3M1:
case Conn_4G_4M1: _do_xG_xM1_xM3(); break;
case Conn_2G_1M2:
case Conn_2G_2M2:
case Conn_2G_3M2:
case Conn_2G_4M2:
case Conn_3G_1M2: _do_xG_xM2(); break;
case Conn_2G_1M3:
case Conn_2G_2M3:
case Conn_2G_3M3:
case Conn_2G_4M3:
case Conn_3G_1M3: _do_xG_xM3 (); break;
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break;
case Conn_2G:
if ( (_east and _west) or (_north and _south) ) {
straightLine = true;
break;
}
case Conn_3G:
case Conn_4G:
_do_xG();
break;
default:
cerr << Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
" The global routing seems to be defective."
, _connexity.connexity
, _connexity.fields.globals
, _connexity.fields.M1
, _connexity.fields.M2
, _connexity.fields.M3
, _connexity.fields.Pin
, _connexity.fields.Pad
, _net->_getString().c_str()
, getString(_gcell).c_str()
) << endl;
_do_xG();
}
if (straightLine) {
// This a global router problem.
cerr << Bug( "Unmanaged configuration: straight line,\n"
" The global routing seems to be defective."
) << endl;
return;
} else {
if (_sourceContact) {
AutoContact* targetContact
= ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) )
? _northEastContact : _southWestContact ;
AutoSegment* globalSegment = AutoSegment::create( _sourceContact
, targetContact
, static_cast<Segment*>( _fromHook->getComponent() )
);
globalSegment->setFlags( (_degree == 2) ? SegBipoint : 0 );
ltrace(99) << "Create global segment: " << globalSegment << endl;
#if THIS_IS_DEPRECATED
if ( globalSegment->isHorizontal()
and ( (Session::getRoutingGauge()->getLayerDepth(_sourceContact->getLayer()->getBottom()) > 1)
or (Session::getRoutingGauge()->getLayerDepth(targetContact ->getLayer()->getBottom()) > 1)) ) {
globalSegment->setLayer ( Session::getRoutingLayer(3) );
ltrace(99) << "Source:" << _sourceContact << endl;
ltrace(99) << "Target:" << targetContact << endl;
ltrace(99) << "Moving up global:" << globalSegment << endl;
}
#endif
// HARDCODED VALUE.
if ( (_topology & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
_toFixSegments.push_back( globalSegment );
if (_connexity.fields.globals < 2) {
ltraceout(99);
return;
}
} else
_fromHook = NULL;
}
if ( _east and (_fromHook != _east) ) {
Hook* toHook = getSegmentOppositeHook( _east );
ltrace(99) << "Pushing East (to) " << getString(toHook) << endl;
ltrace(99) << "Pushing East (from) " << _northEastContact << endl;
forks.push( toHook, _northEastContact );
}
if ( _west and (_fromHook != _west) ) {
Hook* toHook = getSegmentOppositeHook( _west );
ltrace(99) << "Pushing West (to) " << getString(toHook) << endl;
ltrace(99) << "Pushing West (from) " << _southWestContact << endl;
forks.push( toHook, _southWestContact );
}
if ( _north and (_fromHook != _north) ) {
Hook* toHook = getSegmentOppositeHook( _north );
ltrace(99) << "Pushing North (to) " << getString(toHook) << endl;
ltrace(99) << "Pushing North (from) " << _northEastContact << endl;
forks.push( toHook, _northEastContact );
}
if ( _south and (_fromHook != _south) ) {
Hook* toHook = getSegmentOppositeHook( _south );
ltrace(99) << "Pushing South (to) " << getString(toHook) << endl;
ltrace(99) << "Pushing South (from) " << _southWestContact << endl;
forks.push( toHook, _southWestContact );
}
ltraceout(99);
}
void GCellTopology::doRp_AutoContacts ( GCell* gcell
, Component* rp
, AutoContact*& source
, AutoContact*& target
, unsigned int flags
)
{
ltrace(99) << "doRp_AutoContacts()" << endl;
ltracein(99);
ltrace(99) << rp << endl;
source = target = NULL;
Point sourcePosition;
Point targetPosition;
const Layer* rpLayer = rp->getLayer();
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
unsigned int direction = Session::getDirection ( rpDepth );
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
getPositions( rp, sourcePosition, targetPosition );
if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition );
if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition );
GCell* sourceGCell = Session::getKatabatic()->getGCellGrid()->getGCell( sourcePosition );
GCell* targetGCell = Session::getKatabatic()->getGCellGrid()->getGCell( targetPosition );
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
if (rpDepth == 0) {
rpLayer = Session::getContactLayer(0);
direction = KbHorizontal;
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
viaSide = Session::getViaWidth( rpDepth );
}
// Non-M1 terminal or punctual M1 protections.
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
if ((rpDepth != 0) or (sourcePosition == targetPosition)) {
map<Component*,AutoSegment*>::iterator irp = __routingPadAutoSegments.find( rp );
if (irp == __routingPadAutoSegments.end()) {
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
, rp
, rpLayer
, sourcePosition
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
, viaSide, viaSide
);
AutoContact* targetProtect = AutoContactTerminal::create( targetGCell
, rp
, rpLayer
, targetPosition
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
, viaSide, viaSide
);
sourceProtect->setFlags( CntFixed );
targetProtect->setFlags( CntFixed );
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction );
segment->setFlags( SegFixed );
__routingPadAutoSegments.insert( make_pair(rp,segment) );
}
}
if (sourcePosition != targetPosition) {
if (flags & DoSourceContact)
source = AutoContactTerminal::create( sourceGCell
, rp
, rpLayer
, sourcePosition
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
, viaSide, viaSide
);
if (flags & DoTargetContact)
target = AutoContactTerminal::create( targetGCell
, rp
, rpLayer
, targetPosition
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
, viaSide, viaSide
);
}
if (not source and not target) {
source = target = AutoContactTerminal::create( gcell
, rp
, rpLayer
, rp->getCenter()
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
, viaSide, viaSide
);
}
ltraceout(99);
return;
}
AutoContact* GCellTopology::doRp_Access ( GCell* gcell, Component* rp, unsigned int flags )
{
ltrace(99) << "doRp_Access() - flags:" << flags << endl;
ltracein(99);
AutoContact* rpContactSource;
AutoContact* rpContactTarget;
flags |= checkRoutingPadSize( rp );
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
if ( not (flags & HAccess) and (flags & HSmall) ) {
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpContactSource, subContact1, KbHorizontal );
rpContactSource = subContact1;
}
ltraceout(99);
return rpContactSource;
}
void GCellTopology::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 )
{
ltrace(99) << "doRp_StairCaseH()" << endl;
if (rp1->getCenter().getX() > rp2->getCenter().getX()) swap( rp1, rp2 );
AutoContact* rp1ContactSource = NULL;
AutoContact* rp1ContactTarget = NULL;
AutoContact* rp2ContactSource = NULL;
AutoContact* rp2ContactTarget = NULL;
const Layer* viaLayer = NULL;
doRp_AutoContacts( gcell, rp1, rp1ContactSource, rp1ContactTarget, DoTargetContact );
doRp_AutoContacts( gcell, rp2, rp2ContactSource, rp2ContactTarget, DoSourceContact );
if (rp1ContactTarget->getY() == rp2ContactSource->getY()) {
ltrace(99) << "Aligned horizontal routing pads : straight wire" << endl;
viaLayer = rp1->getLayer();
AutoSegment::create( rp1ContactTarget, rp2ContactSource, KbHorizontal );
return;
}
viaLayer = Session::getContactLayer(1);
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp1->getNet(), viaLayer );
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp1->getNet(), viaLayer );
AutoSegment::create( rp1ContactTarget, subContact1 , KbHorizontal );
AutoSegment::create( subContact1 , subContact2 , KbVertical );
AutoSegment::create( subContact1 , rp2ContactSource, KbHorizontal );
}
void GCellTopology::doRp_StairCaseV ( GCell* gcell, Component* rp1, Component* rp2 )
{
ltrace(99) << "doRp_StairCaseV()" << endl;
if (rp1->getCenter().getY() > rp2->getCenter().getY()) swap( rp1, rp2 );
AutoContact* rp1ContactSource = NULL;
AutoContact* rp1ContactTarget = NULL;
AutoContact* rp2ContactSource = NULL;
AutoContact* rp2ContactTarget = NULL;
const Layer* viaLayer = NULL;
doRp_AutoContacts( gcell, rp1, rp1ContactSource, rp1ContactTarget, DoTargetContact );
doRp_AutoContacts( gcell, rp2, rp2ContactSource, rp2ContactTarget, DoSourceContact );
if (rp1ContactTarget->getX() == rp2ContactSource->getX()) {
ltrace(99) << "Aligned vertical routing pads : straight wire" << endl;
viaLayer = rp1->getLayer();
AutoSegment::create( rp1ContactTarget, rp2ContactSource, KbVertical );
return;
}
viaLayer = Session::getContactLayer(1);
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp1->getNet(), viaLayer );
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp1->getNet(), viaLayer );
AutoSegment::create( rp1ContactTarget, subContact1 , KbVertical );
AutoSegment::create( subContact1 , subContact2 , KbHorizontal );
AutoSegment::create( subContact1 , rp2ContactSource, KbVertical );
}
void GCellTopology::_do_xG ()
{
ltrace(99) << "_do_xG()" << endl;
if (_connexity.fields.globals == 2) {
_southWestContact
= _northEastContact
= AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
} else if (_connexity.fields.globals == 3) {
if (_east and _west) {
_southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
_northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) );
if (_south) swap( _southWestContact, _northEastContact );
AutoSegment::create( _southWestContact, _northEastContact, KbVertical );
} else {
_southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
_northEastContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) );
if (_west) swap( _southWestContact, _northEastContact );
AutoSegment::create( _southWestContact, _northEastContact, KbHorizontal );
}
} else { // fields.globals == 4.
AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
_southWestContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) );
_northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( _southWestContact, turn, KbHorizontal );
AutoSegment::create( turn, _northEastContact, KbVertical );
}
}
void GCellTopology::_do_xG_1Pad ()
{
ltrace(99) << "_do_xG_1Pad() [Managed Configuration - Optimized] " << _topology << endl;
ltracein(99);
bool eastPad = false;
bool westPad = false;
bool northPad = false;
bool southPad = false;
Instance* padInstance = dynamic_cast<RoutingPad*>(_routingPads[0])->getOccurrence().getPath().getHeadInstance();
switch ( padInstance->getTransformation().getOrientation() ) {
case Transformation::Orientation::ID: northPad = true; break;
case Transformation::Orientation::YR: eastPad = true; break;
case Transformation::Orientation::R3: eastPad = true; break;
case Transformation::Orientation::MY: southPad = true; break;
case Transformation::Orientation::R1: westPad = true; break;
default:
cerr << Warning( "Unmanaged orientation %s for pad <%s>."
, getString(padInstance->getTransformation().getOrientation()).c_str()
, getString(padInstance).c_str() ) << endl;
break;
}
Point position = _routingPads[0]->getCenter();
AutoContact* source = NULL;
GCell* gcell = Session::getKatabatic()->getGCellGrid()->getGCell(position);
source = AutoContactTerminal::create ( gcell
, _routingPads[0]
, Session::getContactLayer(3)
, position
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
, Session::getViaWidth(3), Session::getViaWidth(3)
);
source->setFlags( CntFixed );
if (northPad or eastPad) {
_southWestContact = _northEastContact = source;
ltraceout(99);
return;
}
// Check for straight lines, which are not managed by _do_xG().
if (_connexity.fields.globals == 1) {
if (westPad and (_east != NULL)) {
AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
_northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( source, turn, KbHorizontal );
AutoSegment::create( turn, _northEastContact, KbVertical );
ltraceout(99);
return;
} else if (southPad and (_north != NULL)) {
AutoContact* turn = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
_northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( source, turn, KbVertical );
AutoSegment::create( turn, _northEastContact, KbHorizontal );
ltraceout(99);
return;
}
}
++_connexity.fields.globals;
--_connexity.fields.Pad;
if (westPad ) _west = source->getBodyHook();
if (southPad) _south = source->getBodyHook();
_do_xG();
if (westPad) {
AutoSegment::create( source, _southWestContact, KbHorizontal );
_west = NULL;
}
if (southPad) {
AutoSegment::create( source, _southWestContact, KbVertical );
_south = NULL;
}
--_connexity.fields.globals;
ltraceout(99);
}
void GCellTopology::_do_1G_1PinM2 ()
{
ltrace(99) << "_do_1G_1PinM2() [Managed Configuration - Optimized] " << _topology << endl;
ltracein(99);
AutoContact* rpContact = doRp_Access( _gcell, _routingPads[0], NoFlags );
AutoContact* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, turn1, KbVertical );
if (_north or _south) {
AutoContact* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( turn1, turn2, KbHorizontal );
turn1 = turn2;
}
_southWestContact = _northEastContact = turn1;
ltraceout(99);
}
void GCellTopology::_do_1G_1M1 ()
{
ltrace(99) << "_do_1G_1M1() [Managed Configuration - Optimized] " << _topology << endl;
ltracein(99);
unsigned int flags = NoFlags;
if (_east ) { flags |= HAccess; }
else if (_west ) { flags |= HAccess; }
else if (_north) { flags |= VSmall; }
else if (_south) { flags |= VSmall; }
_southWestContact = _northEastContact = doRp_Access( _gcell, _routingPads[0], flags );
ltraceout(99);
}
void GCellTopology::_do_1G_xM1 ()
{
ltrace(99) << "_do_1G_" << _connexity.fields.M1 << "M1() [Managed Configuration]" << endl;
ltracein(99);
sort( _routingPads.begin(), _routingPads.end(), SortRpByX(NoFlags) ); // increasing X.
for ( unsigned int i=1 ; i<_routingPads.size() ; ++i ) {
AutoContact* leftContact = doRp_Access( _gcell, _routingPads[i-1], HAccess );
AutoContact* rightContact = doRp_Access( _gcell, _routingPads[i ], HAccess );
AutoSegment::create( leftContact, rightContact, KbHorizontal );
}
Component* globalRp = NULL;
if (_east) globalRp = _routingPads[_routingPads.size()-1];
else if (_west) globalRp = _routingPads[0];
else {
globalRp = _routingPads[0];
ltrace(99) << "| Initial N/S Global RP: " << globalRp << endl;
for ( unsigned int i=1 ; i<_routingPads.size() ; ++i ) {
if (_routingPads[i]->getBoundingBox().getHeight() > globalRp->getBoundingBox().getHeight()) {
ltrace(99) << "| Better RP: " << globalRp << endl;
globalRp = _routingPads[i];
}
}
}
AutoContact* globalContact = doRp_Access( _gcell, globalRp, HAccess );
if (_north or _south) {
AutoContact* turn = globalContact;
globalContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( globalContact, turn, KbHorizontal );
}
_northEastContact = _southWestContact = globalContact;
ltraceout(99);
}
void GCellTopology::_do_xG_1M1_1M2 ()
{
ltrace(99) << "_do_xG_1M1_1M2() [Managed Configuration]" << endl;
ltracein(99);
Component* rpL1;
Component* rpL2;
if (_routingPads[0]->getLayer() == Session::getRoutingLayer(0)) {
rpL1 = _routingPads[0];
rpL2 = _routingPads[1];
} else {
rpL1 = _routingPads[1];
rpL2 = _routingPads[0];
}
ltrace(99) << "rpL1 := " << rpL1 << endl;
ltrace(99) << "rpL2 := " << rpL2 << endl;
AutoContact* rpL1ContactSource = NULL;
AutoContact* rpL1ContactTarget = NULL;
AutoContact* rpL2ContactSource = NULL;
AutoContact* rpL2ContactTarget = NULL;
doRp_AutoContacts( _gcell, rpL1, rpL1ContactSource, rpL1ContactTarget, NoFlags );
doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, NoFlags );
AutoContact* subContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpL1ContactSource, subContact, KbHorizontal );
AutoSegment::create( rpL2ContactSource, subContact, KbVertical );
if (_south or _west) {
doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, DoSourceContact );
if (_south and _west) {
_southWestContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) );
AutoSegment::create( rpL2ContactSource, _southWestContact, KbHorizontal );
} else {
if (_south) {
_southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(2) );
AutoSegment::create( rpL2ContactSource, _southWestContact, KbHorizontal );
} else {
_southWestContact = rpL2ContactSource;
}
}
}
if (_north or _east) {
doRp_AutoContacts( _gcell, rpL2, rpL2ContactSource, rpL2ContactTarget, DoTargetContact );
if (_north and _east) {
_northEastContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) );
AutoSegment::create( rpL2ContactTarget, _northEastContact, KbHorizontal );
} else {
if (_north) {
_northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(2) );
AutoSegment::create( rpL2ContactTarget, _northEastContact, KbHorizontal );
} else {
_northEastContact = rpL2ContactTarget;
}
}
}
ltraceout(99);
}
void GCellTopology::_do_xG_xM1_xM3 ()
{
ltrace(99) << "_do_xG_" << _connexity.fields.M1
<< "M1_" << _connexity.fields.M3
<< "M3() [G:" << _connexity.fields.globals << " Managed Configuration]" << endl;
ltracein(99);
ltrace(99) << "_connexity: " << _connexity.connexity << endl;
ltrace(99) << "_north: " << _north << endl;
ltrace(99) << "_south: " << _south << endl;
ltrace(99) << "_east: " << _east << endl;
ltrace(99) << "_west: " << _west << endl;
Component* rpM3 = NULL;
if (_routingPads[0]->getLayer() == Session::getRoutingLayer(2))
rpM3 = _routingPads[0];
sort( _routingPads.begin(), _routingPads.end(), SortRpByX(NoFlags) ); // increasing X.
for ( unsigned int i=1 ; i<_routingPads.size() ; ++i ) {
AutoContact* leftContact = doRp_Access( _gcell, _routingPads[i-1], HAccess );
AutoContact* rightContact = doRp_Access( _gcell, _routingPads[i ], HAccess );
AutoSegment::create( leftContact, rightContact, KbHorizontal );
if (not rpM3 and (_routingPads[i]->getLayer() == Session::getRoutingLayer(2)))
rpM3 = _routingPads[i];
}
AutoContact* unusedContact = NULL;
if (rpM3) {
// At least one M3 RoutingPad is present: use it.
if (_west and not _south) {
_southWestContact = doRp_Access( _gcell, _routingPads[0], HAccess );
} else if (not _west and _south) {
doRp_AutoContacts( _gcell, rpM3, _southWestContact, unusedContact, DoSourceContact );
} else if (_west and _south) {
AutoContact* rpContact = NULL;
doRp_AutoContacts( _gcell, rpM3, rpContact, unusedContact, DoSourceContact );
_southWestContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _southWestContact, KbVertical );
}
if (_east and not _north) {
_northEastContact = doRp_Access( _gcell, _routingPads[_routingPads.size()-1], HAccess );
} else if (not _east and _north) {
doRp_AutoContacts( _gcell, rpM3, unusedContact, _northEastContact, DoTargetContact );
} else if (_east and _north) {
AutoContact* rpContact = NULL;
doRp_AutoContacts( _gcell, rpM3, unusedContact, rpContact, DoTargetContact );
_northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _northEastContact, KbVertical );
}
} else {
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
// All RoutingPad are M1.
Component* southWestRp = _routingPads[0];
ltrace(99) << "| Initial S-W Global RP: " << southWestRp << endl;
for ( unsigned int i=1 ; i<_routingPads.size() ; ++i ) {
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
if (southWestRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break;
if (_routingPads[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) {
ltrace(99) << "| Better RP: " << southWestRp << endl;
southWestRp = _routingPads[i];
}
}
if (_west and not _south) {
_southWestContact = doRp_Access( _gcell, southWestRp, HAccess );
} else if (not _west and _south) {
AutoContact* rpContact = doRp_Access( _gcell, southWestRp, HAccess );
_southWestContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _southWestContact, KbHorizontal );
} else if (_west and _south) {
AutoContact* rpContact = doRp_Access( _gcell, southWestRp, HAccess );
_southWestContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _southWestContact, KbHorizontal );
* ./katabatic: - New: In AutoSegment, adds a "_parent" attribute to keep track of the fragmentation processus. Currently used only for strap segments, points to the original segment in the appropriate direction (before the split). - New: In GCell & LayerAssign, new method of layer assignment. Move up the whole net trunk if only one of it's segment is inside an over-saturated GCell. AutoSegment are moved up only if there is at least 2 free tracks remaining on the upper level. - Change: In Session::_canonize(), uses the lowest segment Id as canonical. More reliable than geometricals criterions in the end. Assuming that the segments are being created in deterministic order, which *should* be the case consediring the way we are walking through the global routing. - Change: In AutoSegment, completly suppress the CompareCanonical(), replace it by the much simpler CompareId(). - Change: In GCell::rpDesaturate(), stops desaturation when bottom density is under 0.5, otherwise we are causing a severe imbalance in M2/M4 densities. All wires pushed up to M4... - Change: In ChipTools, for the Pad's RoutingPad, reslect the best component using the one in the lowest layer. To avoid problem when splitting AutoContact as we expect the base Contact to be on the lower layer. - Bug: In GCellConfiguration::_GCell_xG_xL1_xL3(), add H/V alignement constraints in fork case. This allow NE/SW contact to be splitted correctly later. - Bug: In AutoContact::split(), the connexity on the splitted contacts was not correctly restored, leading to canonization and parentage looping errors. This was concealed by the Kite Track::_check() bug (incomplete individual TrackSegment checking).
2010-12-30 12:41:19 -06:00
}
Component* northEastRp = _routingPads[_routingPads.size()-1];
ltrace(99) << "| Initial N-E Global RP: " << northEastRp << endl;
if (_routingPads.size() > 1) {
unsigned int i=_routingPads.size()-2;
do {
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
if (northEastRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break;
if (_routingPads[i]->getBoundingBox().getHeight() > northEastRp->getBoundingBox().getHeight()) {
ltrace(99) << "| Better RP: " << northEastRp << endl;
northEastRp = _routingPads[i];
}
} while (i != 0);
}
if (_east and not _north) {
_northEastContact = doRp_Access( _gcell, northEastRp, HAccess );
} else if (not _east and _north) {
AutoContact* rpContact = doRp_Access( _gcell, northEastRp, HAccess );
_northEastContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _northEastContact, KbHorizontal );
} else if (_east and _north) {
AutoContact* rpContact = doRp_Access( _gcell, northEastRp, HAccess );
_northEastContact = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _northEastContact, KbHorizontal );
}
}
ltraceout(99);
}
void GCellTopology::_do_xG_xM2 ()
{
ltrace(99) << "_do_"
<< _connexity.fields.globals << "G_"
<< _connexity.fields.M2 << "M2() [Managed Configuration - x]" << endl;
ltracein(99);
Component* biggestRp = _routingPads[0];
for ( unsigned int i=1 ; i<_routingPads.size() ; ++i ) {
doRp_StairCaseH( _gcell, _routingPads[i-1], _routingPads[i] );
if (_routingPads[i]->getBoundingBox().getWidth() > biggestRp->getBoundingBox().getWidth())
biggestRp = _routingPads[i];
}
AutoContact* unusedContact = NULL;
if (_west and not _south) {
doRp_AutoContacts( _gcell, _routingPads[0], _southWestContact, unusedContact, DoSourceContact );
} else if (not _west and _south) {
_southWestContact = doRp_Access( _gcell, biggestRp, NoFlags );
} else if (_west and _south) {
AutoContact* rpContact = doRp_Access( _gcell, biggestRp, NoFlags );
_southWestContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _southWestContact, KbVertical );
}
if (_east and not _north) {
doRp_AutoContacts( _gcell, _routingPads[_routingPads.size()-1], _northEastContact, unusedContact, DoSourceContact );
} else if (not _east and _north) {
_northEastContact = doRp_Access( _gcell, biggestRp, NoFlags );
} else if (_east and _north) {
AutoContact* rpContact = doRp_Access( _gcell, biggestRp, NoFlags );
_northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _northEastContact, KbVertical );
}
ltraceout(99);
}
void GCellTopology::_do_1G_1M3 ()
{
ltrace(99) << "_do_1G_1M3() [Optimised Configuration]" << endl;
ltracein(99);
unsigned int flags = (_east or _west) ? HAccess : NoFlags;
flags |= (_north) ? DoTargetContact : NoFlags;
flags |= (_south) ? DoSourceContact : NoFlags;
doRp_AutoContacts( _gcell
, _routingPads[0]
, _southWestContact
, _northEastContact
, flags
);
if (not _southWestContact) _southWestContact = _northEastContact;
if (not _northEastContact) _northEastContact = _southWestContact;
ltrace(99) << "_southWest: " << _southWestContact << endl;
ltrace(99) << "_northEast: " << _northEastContact << endl;
if (flags & HAccess) {
// HARDCODED VALUE.
Improved UpdateSession & exception catching. Start of RoutingGauge implem. Miscellaneous: * Change: In <crlcore>, in display.conf use the same display threshold for both METAL2 & METAL3. In alliance.conf, the side of VIAs in the gauge is 2l (not 3l). In kite.conf, separate edge densities for H/V. * Change: In <Cell>, in flattenNets() use flag as argument, not a boolean. Do not create rings for clock or supply nets. * Change: In <DeepNet>, in _createRoutingPads() do not create rings for clock or supply net (duplicated policy as in Cell::flattenNets()). * Bug: In <ControllerWidget>, at last find the bad signal disconnect that was causing ungraceful messages. * Change: In <knik>, in Edge display occupancy/capacity in the string name. Improved display progress and debugging capabilities. Improved exception catch & breakpoint managment: * Bug: In <PaletteWidget>, in updateExtensions() replace the calls to deleteLayer() by delete. This cause the widget to be immediatly erased instead of waiting for the event queue to be completly processed. This was causing the widget to be left in a incoherent state when stoping at a breakpoint. * Bug: In <BreakpointWidget>, in execNoModal(), flush the main event loop (QApplication::flush()) *before* lauching the *local* event loop. This is to ensure all widgets are in their final state when waiting (especially <PaletteWidget>). * Change: In <ExceptionWidget>, new method catchAllWrapper() to execute any std::function< void() > function/method with a "try"/ "catch" wraparound and lauch the widget in case something is catch. * New: In <hurricane>, support for a oberver pattern, backported from <katabatic> with an Obervable capable of being linked to any number of Obervers. * New: In <Cell>, made it observable to detect Cell change, currently emit two kind of signals: - Cell::CellAboutToChange : *before* any change. - Cell::CellChanged : *after* the change has been completed. * New: In <UpdateSession>, in Go::invalidate() add the Cell owning the Go to the UPDATOR_STACK (of course the cell is added only once). In addition, when the Cell is added, send a notification of Cell::CellAboutToChange to all it's observers. The slave instances are also invalidated. Conversely in UpdateSession::_preDestroy() for each invalidated Cell send a Cell::CellChanged notification to all observer. The UPDATOR_STACK has been slightly amended to accept Cell which are not Gos. Prior to this, the Cell where completly excluded from the UpdateSession mechanism, so it's instances where never actualised of anything referring to the Cell for that matter. Note: we use two different mechanisms to transmit a Cell change, observers and the slave instance map. I think at some point it should be unificated. * Change: In <CellViewer>, make it a Cell observer to redraw when the cell is modificated (also update the palette). Uses the catchAllWrapper() to protect all critical actions. * Change: In <GraphicTool>, no longer need of cellPreModificated and cellPostModificated signals. Now done through the Cell obersvers. * Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper method for protection (need to split methods in two, to be able to pass it as argument). No longer emit cellPreModificated and cellPostModificated. Support for RoutingGauge in P&R: * Bug: In <placeandroute.py>, the connection from the internal power ring to the connectors was not done correctly. Wrong contact layers leading to a gap. * Change: In <BuildPowerRails>, detection of the corona signals based on how the "pck_px" pad is connected. No longer based on name matching. * Change: In <placeandroute.py>, support for 2 routing metal only (3 metal in the technology). * Change: In <katabatic> & <kite> support for a "top layer" limitation on the routing gauge, this allows to use only two routing metals (METAL2 & METAL3). Work in progress.
2014-04-20 12:25:08 -05:00
if (_routingPads[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) {
AutoContact* subContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( _southWestContact, subContact, KbVertical );
_southWestContact = _northEastContact = subContact;
}
} else {
if (_sourceContact) {
if (_sourceContact->getX() != _southWestContact->getX()) {
AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( _southWestContact, turn1, KbVertical );
AutoSegment::create( turn1 , turn2, KbHorizontal );
_southWestContact = _northEastContact = turn2;
}
}
}
ltraceout(99);
}
void GCellTopology::_do_xG_xM3 ()
{
ltrace(99) << "_do_xG_" << _connexity.fields.M3
<< "M3() [Managed Configuration]" << endl;
ltracein(99);
ltrace(99) << "_west:" << _west << endl;
ltrace(99) << "_east:" << _east << endl;
ltrace(99) << "_south:" << _south << endl;
ltrace(99) << "_north:" << _north << endl;
sort( _routingPads.begin(), _routingPads.end(), SortRpByY(NoFlags) ); // increasing Y.
for ( unsigned int i=1 ; i<_routingPads.size() ; i++ ) {
doRp_StairCaseV( _gcell, _routingPads[i-1], _routingPads[i] );
}
AutoContact* unusedContact = NULL;
Component* rp = _routingPads[0];
if (_west and not _south) {
_southWestContact = doRp_Access( _gcell, rp, HAccess );
} else if (not _west and _south) {
doRp_AutoContacts( _gcell, rp, _southWestContact, unusedContact, DoSourceContact );
if (_sourceContact) {
if (_sourceContact->getX() != _southWestContact->getX()) {
ltrace(200) << "Misaligned South: _source:" << DbU::getValueString(_sourceContact->getX())
<< "_southWest:" << DbU::getValueString(_southWestContact->getX()) << endl;
AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( _southWestContact, turn1, KbVertical );
AutoSegment::create( turn1 , turn2, KbHorizontal );
_southWestContact = turn2;
}
}
} else if (_west and _south) {
AutoContact* rpContact = NULL;
doRp_AutoContacts( _gcell, rp, rpContact, unusedContact, DoSourceContact );
_southWestContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _southWestContact, KbVertical );
}
rp = _routingPads[_routingPads.size()-1];
if (_east and not _north) {
_northEastContact = doRp_Access( _gcell, rp, HAccess );
} else if (not _east and _north) {
doRp_AutoContacts( _gcell, rp, unusedContact, _northEastContact, DoTargetContact );
if (_sourceContact) {
if (_sourceContact->getX() != _northEastContact->getX()) {
ltrace(200) << "Misaligned North: _source:" << DbU::getValueString(_sourceContact->getX())
<< "_southWest:" << DbU::getValueString(_northEastContact->getX()) << endl;
AutoContactTurn* turn1 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoContactTurn* turn2 = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( _northEastContact, turn1, KbVertical );
AutoSegment::create( turn1 , turn2, KbHorizontal );
_northEastContact = turn2;
}
}
} else if (_east and _north) {
AutoContact* rpContact = NULL;
doRp_AutoContacts( _gcell, rp, unusedContact, rpContact, DoTargetContact );
_northEastContact = AutoContactVTee::create( _gcell, _net, Session::getContactLayer(1) );
AutoSegment::create( rpContact, _northEastContact, KbVertical );
}
ltraceout(99);
}
void singleGCell ( KatabaticEngine* ktbt, Net* net )
{
ltrace(99) << "singleGCell() " << net << endl;
ltracein(99);
vector<Component*> rpM1s;
Component* rpM2 = NULL;
forEach ( RoutingPad*, irp, net->getRoutingPads() ) {
if (Session::getRoutingGauge()->getLayerDepth(irp->getLayer()) == 1)
rpM2 = *irp;
else
rpM1s.push_back( *irp );
}
if ((rpM1s.size() < 2) and not rpM2) {
cerr << Error( "For %s, less than two Plugs/Pins (%d)."
, getString(net).c_str()
, rpM1s.size() ) << endl;
ltraceout(99);
return;
}
sort( rpM1s.begin(), rpM1s.end(), SortRpByX(NoFlags) ); // increasing X.
GCell* gcell = ktbt->getGCellGrid()->getGCell( (*rpM1s.begin ())->getCenter()
, (*rpM1s.rbegin())->getCenter() );
if (not gcell) {
cerr << Error( "No GCell under %s.", getString(rpM1s[0]).c_str() ) << endl;
ltraceout(99);
return;
}
ltrace(80) << "singleGCell " << gcell << endl;
AutoContact* turn = NULL;
AutoContact* source = NULL;
AutoContact* target = NULL;
for ( size_t irp=1 ; irp<rpM1s.size() ; ++irp ) {
GCellTopology::doRp_AutoContacts( gcell, rpM1s[irp-1], source, turn, DoSourceContact );
GCellTopology::doRp_AutoContacts( gcell, rpM1s[irp ], target, turn, DoSourceContact );
AutoSegment::create( source, target, KbHorizontal );
}
if (rpM2) {
GCellTopology::doRp_AutoContacts( gcell, rpM1s[0], source, turn, DoSourceContact );
GCellTopology::doRp_AutoContacts( gcell, rpM2 , target, turn, DoSourceContact );
turn = AutoContactTurn::create( gcell, rpM2->getNet(), Session::getContactLayer(1) );
AutoSegment::create( source, turn , KbHorizontal );
AutoSegment::create( turn , target, KbVertical );
}
ltraceout(99);
}
} // Anonymous namespace.
namespace Katabatic {
using Hurricane::ltracein;
using Hurricane::ltraceout;
using Hurricane::ltracelevel;
using Hurricane::Name;
using Hurricane::DebugSession;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Bug;
using CRL::addMeasure;
using CRL::getMeasure;
void KatabaticEngine::_loadGrByNet ()
{
cmess1 << " o Loading Nets global routing from Knik." << endl;
cmess1 << Dots::asDouble(" - Saturation",getMeasure<double>(getCell(),"Sat.")->getData()) << endl;
startMeasures();
Session::open( this );
NetSet::iterator inet = _routingNets.begin();
while ( inet != _routingNets.end() ) {
DebugSession::open( *inet, 80 );
_loadNetGlobalRouting( *(inet++) );
Session::revalidate();
DebugSession::close();
}
#if defined(CHECK_DATABASE)
_check ( "after Katabatic loading" );
#endif
_print();
Session::close();
stopMeasures();
printMeasures( "load" );
addMeasure<size_t>( getCell(), "Globals", AutoSegment::getGlobalsCount() );
addMeasure<size_t>( getCell(), "Edges" , AutoSegment::getAllocateds() );
}
void KatabaticEngine::_loadNetGlobalRouting ( Net* net )
{
ltrace(100) << "Katabatic::_loadNetGlobalRouting( " << net << " )" << endl;
ltracein(99);
ForkStack forks;
Hook* sourceHook = NULL;
AutoContact* sourceContact = NULL;
lookupClear();
RoutingPads routingPads = net->getRoutingPads();
size_t degree = routingPads.getSize();
if (degree == 0) {
cmess2 << Warning("Net \"%s\" do not have any RoutingPad (ignored)."
,getString(net->getName()).c_str()) << endl;
ltraceout(99);
return;
}
if (degree < 2) {
#if 0
if ( !getDemoMode() )
cmess2 << Warning("Net \"%s\" have less than 2 plugs/pins (ignored)."
,getString(net->getName()).c_str()) << endl;
#endif
ltraceout(99);
return;
}
ltracein(99);
Hook* startHook = NULL;
GCell* lowestGCell = NULL;
size_t unconnecteds = 0;
size_t connecteds = 0;
GCellTopology::init( degree );
ltrace(99) << "Start RoutingPad Ring" << endl;
forEach ( RoutingPad*, startRp, routingPads ) {
bool segmentFound = false;
forEach ( Hook*, ihook, startRp->getBodyHook()->getHooks() ) {
ltrace(99) << "Component " << ihook->getComponent() << endl;
Segment* segment = dynamic_cast<Segment*>( ihook->getComponent() );
if (segment) {
++connecteds;
segmentFound = true;
GCellTopology gcellConf ( getGCellGrid(), *ihook, NULL );
if (gcellConf.getStateG() == 1) {
if ( (lowestGCell == NULL) or (lowestGCell->getIndex() > gcellConf.getGCell()->getIndex()) ) {
ltrace(99) << "Starting from GCell " << gcellConf.getGCell() << endl;
lowestGCell = gcellConf.getGCell();
startHook = *ihook;
}
break;
}
}
}
unconnecteds += (segmentFound) ? 0 : 1;
if ( (unconnecteds > 10) and (connecteds == 0) ) {
cerr << Warning("More than 10 unconnected RoutingPads (%u) on %s, missing global routing?"
,unconnecteds, getString(net->getName()).c_str() ) << endl;
_routingNets.erase( net );
ltraceout(99);
return;
}
// Uncomment the next line to disable the lowest GCell search.
// (takes first GCell with exactly one global).
//if (startHook) break;
}
ltraceout(99);
if (startHook == NULL) { singleGCell( this, net ); ltraceout(99); return; }
GCellTopology startGCellConf ( getGCellGrid(), startHook, NULL );
startGCellConf.construct( forks );
sourceHook = forks.getFrom ();
sourceContact = forks.getContact();
forks.pop();
while ( sourceHook ) {
GCellTopology gcellConf ( getGCellGrid(), sourceHook, sourceContact );
gcellConf.construct( forks );
sourceHook = forks.getFrom();
sourceContact = forks.getContact();
forks.pop();
ltrace(99) << "Popping (from) " << sourceHook << endl;
ltrace(99) << "Popping (to) " << sourceContact << endl;
}
lookupClear();
Session::revalidate();
#if THIS_IS_DISABLED
set<AutoSegment*>::iterator iover = overconstraineds.begin();
for ( ; iover != overconstraineds.end() ; ++iover ) {
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
}
#endif
Session::revalidate();
GCellTopology::fixSegments();
ltraceout(99);
}
} // Katabatic namespace.