coriolis/knik/src/Graph.cpp

2675 lines
107 KiB
C++
Raw Normal View History

#include <cmath>
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
#include <sstream>
#include <algorithm>
#include <memory>
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
#include "hurricane/DebugSession.h"
#include "hurricane/Warning.h"
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
#include "hurricane/Error.h"
#include "hurricane/Name.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Component.h"
#include "hurricane/Net.h"
#include "hurricane/DeepNet.h"
#include "hurricane/Cell.h"
#include "hurricane/Technology.h"
#include "hurricane/DataBase.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/Breakpoint.h"
#include "crlcore/Utilities.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/RoutingLayerGauge.h"
#include "knik/Configuration.h"
#include "knik/Graph.h"
#include "knik/Vertex.h"
#include "knik/Edge.h"
#include "knik/HEdge.h"
#include "knik/VEdge.h"
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
#include "knik/KnikEngine.h"
#include "knik/flute.h"
//#define __USE_SLICINGTREE__
#define __USE_MATRIXVERTEX__
#define EPSILON 10e-4
#define FLUTE_LIMIT 150
#define HISTORIC_INC 1.5 // define the increment of historic cost for ripup & reroute
namespace Knik {
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
using Hurricane::inltrace;
using Hurricane::ltracein;
using Hurricane::ltraceout;
using Hurricane::tab;
using Hurricane::ForEachIterator;
int depthMaterialize;
unsigned countDijkstra = 0;
unsigned countMonotonic = 0;
unsigned countMaterialize = 0;
bool debugging;
Name debugName = Name("");
bool __ripupMode__;
extern float __edge_capacity_percent__;
extern unsigned __congestion__;
extern unsigned __precongestion__;
using namespace CRL;
STuple::STuplePQIter STuple::_stuplePQEnd;
Name STuple::CostProperty::_name = "Knik::CostProperty";
struct segmentStat {
unsigned nbDep;
unsigned nbTot;
unsigned sumOv;
segmentStat(unsigned dep, unsigned tot, unsigned ov) { nbDep=dep; nbTot=tot; sumOv=ov; };
segmentStat() {};
~segmentStat() {};
void incNbDep() { nbDep++; };
void incNbTot() { nbTot++; };
void incSumOv ( unsigned inc ) { sumOv+=inc; };
unsigned getNbDep() const { return nbDep; };
unsigned getNbTot() const { return nbTot; };
unsigned getSumOv() const { return sumOv; };
};
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
Graph::Graph ( KnikEngine* engine, RoutingGrid* routingGrid, bool benchMode, bool useSegments )
// ********************************************************************************************
: _cell ( engine->getCell() )
, _engine ( engine )
, _benchMode ( benchMode )
, _useSegments ( useSegments )
, _slicingTree ( NULL )
, _matrixVertex ( NULL )
, _routingGrid ( routingGrid )
, _working_net ( NULL )
, _vertexes_to_route()
, _lowerLeftVertex ( NULL )
, _all_vertexes()
, _all_edges()
, _nbSplitters ( 0 )
, _vtuplePriorityQueue()
, _stuplePriorityQueue()
, _searchingArea()
, _xSize ( 0 )
, _ySize ( 0 )
//, _estimateOccupancyWindow ( NULL )
//, _occupancyWindow ( NULL )
, _maxEstimateOccupancy ( 0.0 )
, _maxXEstimateOccupancy ( 0.0 )
, _maxYEstimateOccupancy ( 0.0 )
, _maxOccupancy ( 0 )
, _maxXOccupancy ( 0 )
, _maxYOccupancy ( 0 )
, _hEdgeNormalisedLength ( 1.0 ) // au cas ou
, _vEdgeNormalisedLength ( 1.0 ) // au cas ou
{
__ripupMode__ = false;
}
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
Graph* Graph::create ( KnikEngine* engine, RoutingGrid* routingGrid, bool benchMode, bool useSegments )
// ****************************************************************************************************
{
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
Graph* _graph = new Graph ( engine, routingGrid, benchMode, useSegments );
_graph->_postCreate();
return _graph;
}
void Graph::_postCreate()
// **********************
{
_netStamp = 1; // initializing netStamp here instead of in Knik::Route function (for reroute, it seems good)
//Cell* cell = _nimbus->getCell();
//DisplaySlot* vertexDS = DisplaySlot::create( cell, Name("KnikVertexDS"),192, 0 ,192,"FFFFFFFFFFFFFFFF",1,192, 0 ,192,"FFFFFFFFFFFFFFFF",1 );
//DisplaySlot* edgeDS = DisplaySlot::create( cell, Name("KnikEdgeDS") ,153,100, 17,"55AA55AA55AA55AA",1,153,100, 17,"55AA55AA55AA55AA",1 );
// XXX On supprime tout ce qui concerne NIMBUS et on considère qu'il existe toujours une _routingGrid XXX
if ( !_routingGrid ) {
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
#ifdef __USE_MATRIXVERTEX__
_matrixVertex = MatrixVertex::create(this);
if( !_matrixVertex )
throw Error ("Graph::_postCreate(): cannot create MatrixVertex");
_lowerLeftVertex = _matrixVertex->createRegularMatrix ();
cmess2 << " - Created vertex matrix (without RoutingGrid)" << endl;
#else
throw Error ("Graph::_postCreate(): cannot use another method than MatrixVertex");
#endif
// il faut définir les normalisedLength, pour l'instant on le fait pas
} else {
cmess2 << " - RoutingGrid size [" << _routingGrid->getNbXTiles() << "x" << _routingGrid->getNbYTiles() << "]." << endl;
#ifdef __USE_MATRIXVERTEX__
_matrixVertex = MatrixVertex::create(this);
if( !_matrixVertex )
throw Error ("Graph::_postCreate(): cannot create MatrixVertex");
_lowerLeftVertex = _matrixVertex->createRegularMatrix ( _routingGrid );
// initialisation des normalisedLength
float hEdgeLength = _routingGrid->getTileWidth();
float vEdgeLength = _routingGrid->getTileHeight();
_hEdgeNormalisedLength = hEdgeLength <= vEdgeLength ? 1.0 : hEdgeLength / vEdgeLength;
_vEdgeNormalisedLength = hEdgeLength <= vEdgeLength ? vEdgeLength / hEdgeLength : 1.0;
cmess2 << " - Created vertex matrix (from RoutingGrid)." << endl;
#else
throw Error ("Graph::_postCreate(): cannot use another method than MatrixVertex");
#endif
}
if (_lowerLeftVertex->getHEdgeOut())
cout << Dots::asUInt (" - Global router H edges capacity" ,_lowerLeftVertex->getHEdgeOut()->getCapacity()) << endl;
else
cerr << Warning( "Knik::Graph: Design has only one column, H edge capacity is zero." ) << endl;
if (_lowerLeftVertex->getVEdgeOut())
cout << Dots::asUInt (" - Global router V edges capacity" ,_lowerLeftVertex->getVEdgeOut()->getCapacity()) << endl;
else
cerr << Warning( "Knik::Graph: Design has only one row, V edge capacity is zero." ) << endl;
// #ifdef __USE_MATRIXVERTEX__
// _matrixVertex = MatrixVertex::create(this);
// if ( _routingGrid ) {
// _matrixVertex->createXRegular ( _routingGrid );
// _matrixVertex->createYRegular ( _routingGrid );
// }
// else {
// _matrixVertex->createXIrregular ( _nimbus );
// _matrixVertex->createYIrregular ( _nimbus );
// }
// #endif
// #ifdef __USE_SLICINGTREE__
// _slicingTree = SlicingTree::create ( _nimbus );
// #endif
//
// unsigned compteur = 0;
// for_each_gcell ( gcell, _nimbus->getRoutingLeaves() )
// {
// compteur++;
// Vertex* vertex = Vertex::create ( gcell, this );
// if ( !_lowerLeftVertex )
// _lowerLeftVertex = vertex;
// else {
// if ( vertex->getX() <= _lowerLeftVertex->getX() ) {
// if ( vertex->getY() <= _lowerLeftVertex->getY() )
// _lowerLeftVertex = vertex;
// }
// }
// _all_vertexes.push_back ( vertex );
// #ifdef __USE_MATRIXVERTEX__
// _matrixVertex->setVertex ( gcell->getCenter(), vertex );
// #endif
// #ifdef __USE_SLICINGTREE__
// SlicingTreeNode* terminalNode = _slicingTree->getTerminalNode ( gcell->getCenter() );
// terminalNode->setVertex ( vertex );
// #endif
// end_for;
// }
// cmess2 << " - Parcours des gcells pour créer les vertex terminé : " << compteur << " vertex" << endl;
//
// Vertex* currentVertex = _lowerLeftVertex;
// while ( currentVertex ) {
// Vertex* firstLineVertex = currentVertex;
// while ( currentVertex ) {
// GCell* source = currentVertex->getGCell();
// Fence* fenceUP = source->getUpFence();
// GCell* targetUP = source->getUpOfMe();
// if ( targetUP )
// createVEdge ( currentVertex, getVertex ( targetUP->getCenter() ), fenceUP );
// Fence* fenceRIGHT = source->getRightFence();
// GCell* targetRIGHT = source->getRightOfMe();
// if ( targetRIGHT ) {
// Vertex* rightVertex = getVertex ( targetRIGHT->getCenter() );
// createHEdge ( currentVertex, rightVertex, fenceRIGHT );
// currentVertex = rightVertex;
// }
// else
// break;
// }
// Edge* vEdgeOut = firstLineVertex->getVEdgeOut();
// if ( vEdgeOut )
// currentVertex = vEdgeOut->getOpposite ( firstLineVertex );
// else
// break;
// }
// cmess2 << " - Parcours des gcells puis des fences pour créer les edges terminé" << endl;
for ( unsigned i = 0 ; i < _all_vertexes.size() ; i++ ) {
_all_vertexes[i]->sortEdges();
}
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
cmess2 << " - Edge sorting completed." << endl;
STuple::setSTuplePQEnd ( _stuplePriorityQueue.end() );
// cmess2 << "Petites stats :" << endl
// << " gcell : " << sizeof(GCell) << endl
// << " fence : " << sizeof(Fence) << endl
// << " vertex : " << sizeof(Vertex) << endl
// << " edge : " << sizeof (Edge) << endl
// << " net : " << sizeof(Net) << endl
// << " pin : " << sizeof(Pin) << endl
// << " splitter : " << sizeof(Splitter) << endl
// << " splitterContact : " << sizeof(SplitterContact) << endl;
}
void Graph::destroy()
// *****************
{
_preDestroy();
delete this;
}
void Graph::_preDestroy()
// *********************
{
// Destruction of all VTuples
for ( VTuplePQIter pqit = _vtuplePriorityQueue.begin() ; pqit != _vtuplePriorityQueue.end() ; pqit++ ) {
(*pqit)->destroy();
}
// Destrucion of all Edges and Vertexes
Vertex* currentVertex = _lowerLeftVertex;
while ( currentVertex ) {
Vertex* nextVVertex;
if ( Edge* vEdgeOut = currentVertex->getVEdgeOut() )
nextVVertex = vEdgeOut->getOpposite ( currentVertex );
else
nextVVertex = NULL;
while ( currentVertex ) {
if ( Edge* vEdgeOut = currentVertex->getVEdgeOut() )
vEdgeOut->destroy();
Vertex* nextHVertex;
if ( Edge* hEdgeOut = currentVertex->getHEdgeOut() ) {
nextHVertex = hEdgeOut->getOpposite ( currentVertex );
hEdgeOut->destroy();
}
else
nextHVertex = NULL;
currentVertex->destroy();
currentVertex = nextHVertex;
}
currentVertex = nextVVertex;
}
//// Destruction of all Edges
//for ( unsigned i = 0 ; i < _all_edges.size() ; i++ ) {
// _all_edges[i]->destroy();
//}
//// Destruction of all Vertexes
//for ( unsigned i = 0 ; i < _all_vertexes.size() ; i++ ) {
// _all_vertexes[i]->destroy();
//}
#ifdef __USE_MATRIXVERTEX__
_matrixVertex->destroy();
#endif
#ifdef __USE_SLICINGTREE__
_slicingTree->destroy();
#endif
}
Vertex* Graph::getPredecessor ( const Vertex* vertex )
// ***************************************************
{
assert( vertex->getPredecessor() );
return vertex->getPredecessor()->getOpposite ( vertex );
}
Vertex* Graph::getCentralVertex()
// ******************************
{
assert ( _vertexes_to_route.begin() != _vertexes_to_route.end() );
// This function skims the _vertexes_to_route set and returns the most centered vertex.
//
// first pass : builds the bounding box of all vertexes
Box vertexesBBox;
VertexSetIter vsit = _vertexes_to_route.begin();
while ( vsit != _vertexes_to_route.end() ) {
vertexesBBox.merge((*vsit)->getPosition());
vsit++;
}
// second pass : finds the most centered vertex
Point boxCenter = vertexesBBox.getCenter();
vsit = _vertexes_to_route.begin();
Vertex* mostCentered = (*vsit);
DbU::Unit minDistance = boxCenter.manhattanDistance ( mostCentered->getPosition() );
vsit++;
while ( vsit != _vertexes_to_route.end() ) {
Vertex* currentVertex = (*vsit);
DbU::Unit currentDistance = boxCenter.manhattanDistance( currentVertex->getPosition() );
if ( currentDistance < minDistance ) {
mostCentered = currentVertex;
minDistance = currentDistance;
}
vsit++;
}
return mostCentered;
}
Vertex* Graph::getVertex ( Point p )
// *********************************
{
Vertex* vertex;
#ifdef __USE_MATRIXVERTEX__
vertex = _matrixVertex->getVertex(p);
assert(vertex);
#endif
#ifdef __USE_SLICINGTREE__
vertex = _slicingTree->getVertex ( p );
assert ( vertex );
//#else // Ce n'est plus une option !
// GCell* gcell = _nimbus->getRoutingLeafContaining ( p );
// assert ( gcell );
// vertex = getVertexOfGCell ( gcell );
// assert ( vertex );
#endif
return vertex;
}
Vertex* Graph::getVertex ( DbU::Unit x, DbU::Unit y )
// **************************************************
{
return getVertex ( Point(x,y) );
}
unsigned Graph::getGridLength ( Segment* segment )
// ***********************************************
{
// new time-optimized version 02/02/09
unsigned sourceColId = _matrixVertex->getColumnIndex ( segment->getSourceX() );
unsigned targetColId = _matrixVertex->getColumnIndex ( segment->getTargetX() );
unsigned sourceRowId = _matrixVertex->getLineIndex ( segment->getSourceY() );
unsigned targetRowId = _matrixVertex->getLineIndex ( segment->getTargetY() );
if ( sourceColId == targetColId )
return targetRowId - sourceRowId;
else
return targetColId - sourceColId;
//if ( isAGlobalRoutingSegment(segment) ) {
// if ( Horizontal* horiz = dynamic_cast<Horizontal*>(segment) ) {
// unsigned sourceId = _matrixVertex->getColumnIndex ( horiz->getSourceX() );
// unsigned targetId = _matrixVertex->getColumnIndex ( horiz->getTargetX() );
// assert ( sourceId != targetId );
// return targetId - sourceId; // On considere que les segments sont bien orientes !!!!
// }
// else if ( Vertical* verti = dynamic_cast<Vertical*>(segment) ) {
// unsigned sourceId = _matrixVertex->getLineIndex ( verti->getSourceY() );
// unsigned targetId = _matrixVertex->getLineIndex ( verti->getTargetY() );
// assert ( sourceId != targetId );
// return targetId - sourceId; // meme hypothese !!!
// }
// else
// throw Error ( "Graph::getGridLength(): segment is neither horizontal nor vertical." );
//}
return 0;
}
unsigned Graph::getCongestEdgeNb ( Segment* segment )
// **************************************************
{
if ( !isAGlobalRoutingSegment(segment) ) {
string message = "getCongestEdgeNb only treats global routing segment for now : ";
message += getString(segment);
throw Warning ( message );
}
unsigned nbEdge = 0;
if ( dynamic_cast<Horizontal*>(segment) ) {
Vertex* current = getVertex ( segment->getSource()->getCenter() );
Vertex* target = getVertex ( segment->getTarget()->getCenter() );
while ( current != target ) {
Edge* edge = current->getHEdgeOut();
if ( !edge ) throw Error ("Graph::getCongestEdgeNb(): Wow! NULL horizontal Edge.");
if ( edge->isCongested() )
nbEdge++;
current = edge->getTo();
}
}
else if ( dynamic_cast<Vertical*>(segment) ) {
Vertex* current = getVertex ( segment->getSource()->getCenter() );
Vertex* target = getVertex ( segment->getTarget()->getCenter() );
while ( current != target ) {
Edge* edge = current->getVEdgeOut();
if ( !edge ) throw Error ("Graph::getCongestEdgeNb(): Wow! NULL vertical Edge.");
if ( edge->isCongested() )
nbEdge++;
current = edge->getTo();
}
}
else
throw Error ( "Graph::getCongestEdgeNb(): segment is neither horizontal nor vertical." );
return nbEdge++;
}
Segment* Graph::createSegment ( Contact* initialContact, Contact* reachedContact )
// *******************************************************************************
{
//cerr << "Graph::createSegment: " << initialContact << " -- " << reachedContact << endl;
if ( initialContact->getX() == reachedContact->getX() ) {
const Layer* layer = Configuration::getGMetalV();
DbU::Unit xCoord = initialContact->getX();
DbU::Unit width = DbU::lambda(2);
if ( initialContact->getY() <= reachedContact->getY() )
return Vertical::create ( initialContact, reachedContact, layer, xCoord, width );
else
return Vertical::create ( reachedContact, initialContact, layer, xCoord, width );
}
else if ( initialContact->getY() == reachedContact->getY() ) {
const Layer* layer = Configuration::getGMetalH();
DbU::Unit yCoord = initialContact->getY();
DbU::Unit height = DbU::lambda(2);
if ( initialContact->getX() <= reachedContact->getX() )
return Horizontal::create ( initialContact, reachedContact, layer, yCoord, height );
else
return Horizontal::create ( reachedContact, initialContact, layer, yCoord, height );
}
else
throw Error ( "Graph::createSegment(): Contacts are not aligneds." );
}
void Graph::sortHVertexes ( Vertex*& from, Vertex*& to )
// *****************************************************
{
// This function sorts 2 vertexes horizontally:
// from will be the leftest one
assert (from);
assert (to);
if ( from->getX() > to->getX() ) {
Vertex* temp = from;
from = to;
to = temp;
}
}
void Graph::sortVVertexes ( Vertex*& from, Vertex*& to )
// *****************************************************
{
// This function sorts 2 vertexes vertically:
// from will be the downest one
assert (from);
assert (to);
if ( from->getY() > to->getY() ) {
Vertex* temp = from;
from = to;
to = temp;
}
}
Vertex* Graph::createVertex ( Point position, DbU::Unit halfWidth, DbU::Unit halfHeight )
// **************************************************************************************
{
Vertex* vertex = Vertex::create ( this, position, halfWidth, halfHeight );
assert ( vertex );
_all_vertexes.push_back ( vertex );
return vertex;
}
void Graph::createHEdge ( Vertex* from, Vertex* to, size_t reserved )
// ********************************************************************
{
size_t capacity = 0;
if ( _routingGrid ) {
capacity = _routingGrid->getHCapacity();
//cerr << "createHEdge capacity:" << capacity << " reserved:" << reserved << endl;
} 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
vector<RoutingLayerGauge*> rtLGauges = _engine->getRoutingGauge()->getLayerGauges();
for ( vector<RoutingLayerGauge*>::iterator it = rtLGauges.begin() ; it != rtLGauges.end() ; it++ ) {
RoutingLayerGauge* routingLayerGauge = (*it);
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 (routingLayerGauge->getType() != Constant::Default) continue;
if (routingLayerGauge->getDepth() > _engine->getAllowedDepth()) continue;
if (routingLayerGauge->getDirection() != Constant::Horizontal)
continue;
capacity += routingLayerGauge->getTrackNumber ( from->getYMin(), from->getYMax() ) - 1;
}
//cerr << "createHEdge capacity:" << capacity << " reserved:" << reserved << endl;
}
Edge* newEdge = HEdge::create ( from, to, capacity-reserved );
_all_edges.push_back ( newEdge );
newEdge->setCost(1);
Edge* previousEdge = from->getHEdgeOut();
if ( previousEdge )
newEdge->setNextFrom ( previousEdge );
from->setHEdgeOut ( newEdge );
previousEdge = to->getHEdgeIn();
if ( previousEdge )
newEdge->setNextTo ( previousEdge );
to->setHEdgeIn ( newEdge );
}
void Graph::createVEdge ( Vertex* from, Vertex* to, size_t reserved )
// ******************************************************************
{
size_t capacity = 0;
if ( _routingGrid )
capacity = _routingGrid->getVCapacity();
else {
vector<RoutingLayerGauge*> rtLGauges = AllianceFramework::get()->getRoutingGauge()->getLayerGauges();
for ( vector<RoutingLayerGauge*>::iterator it = rtLGauges.begin() ; it != rtLGauges.end() ; it++ ) {
RoutingLayerGauge* routingLayerGauge = (*it);
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 (routingLayerGauge->getType() != Constant::Default) continue;
if (routingLayerGauge->getDepth() > _engine->getAllowedDepth()) continue;
if (routingLayerGauge->getDirection() != Constant::Vertical)
continue;
capacity += routingLayerGauge->getTrackNumber ( from->getXMin(), from->getXMax() ) - 1;
}
//cerr << "createVEdge capacity:" << capacity << " reserved:" << reserved << endl;
}
Edge* newEdge = VEdge::create ( from, to, capacity-reserved );
_all_edges.push_back ( newEdge );
newEdge->setCost(1);
Edge* previousEdge = from->getVEdgeOut();
if ( previousEdge )
newEdge->setNextFrom ( previousEdge );
from->setVEdgeOut ( newEdge );
previousEdge = to->getVEdgeIn();
if ( previousEdge )
newEdge->setNextTo ( previousEdge );
to->setVEdgeIn ( newEdge );
}
void Graph::initConnexComp ( Vertex* vertex, int newConnexID )
// ***********************************************************
{
initConnexComp ( vertex, NULL, newConnexID );
}
void Graph::initConnexComp ( Vertex* vertex, Edge* arrivalEdge, int newConnexID )
// ******************************************************************************
{
// This recursive function initializes all vertexes of same connexID and connected through edges of same connexID,
// which means that the vertex's distance is set to 0 and the vertex is inserted in the VTuplePriorityQueue
// If newConnexID is different from -1, then the connexID is set to newConnexID
int vertexConnex = vertex->getConnexID();
assert ( vertexConnex != -1 );
for_each_edge ( edge, vertex->getAdjacentEdges() ) {
if ( edge == arrivalEdge ) {
continue;
}
if ( (edge->getNetStamp() == _netStamp) && (edge->getConnexID() == vertexConnex) ) {
initConnexComp ( edge->getOpposite(vertex), edge, newConnexID );
if ( newConnexID != -1 ) {
edge->setConnexID(newConnexID);
}
}
end_for;
}
vertex->setDistance(0);
if ( newConnexID != -1 ) {
vertex->setConnexID ( newConnexID );
}
VTuple* vtuple = vertex->getVTuple();
if ( vtuple ) {
//cerr << " Vertex " << vertex << " already has a vtuple : " << vtuple << endl;
assert ( vtuple->getVertex() == vertex );
increaseVTuplePriority ( vtuple, 0 );
}
else {
vtuple = VTuple::create ( vertex, 0 );
//cerr << " Vertex " << vertex << " has now a new vtuple : " << vtuple << endl;
addVTupleToPriorityQueue ( vtuple );
}
}
void Graph::UpdateConnexComp ( VertexList reachedVertexes, Vertex* firstVertex )
// *****************************************************************************
{
// XXX PLUTOT QUE DE PASSER UNE LISTE DE VERTEX EN ARG, ON DEVRAIT PASSER SEULEMENT UN VERTEX XXX
// XXX proviens du fait qu'au depart on voulait reellement passer une liste mais du fait de la possiblité de chemins paralleles on evite XXX
int firstConnexID = firstVertex->getConnexID();
VertexListIter lvit = reachedVertexes.begin();
// Pour essayer d'éviter le bug des chemins parallèles si 2 vertex sont atteints avec la meme distance, on ne va updater que le premier
//while ( lvit != reachedVertexes.end() ) {
Vertex* currentVertex = (*lvit);
int currentConnexID = currentVertex->getConnexID();
//cerr << "Gonna updateConnexComp : first: " << firstVertex << ", reached: " << currentVertex << endl;
//cerr << " vertexes_to_route :" << endl;
//for ( VertexSetIter vsit = _vertexes_to_route.begin() ; vsit != _vertexes_to_route.end() ; vsit++ )
// cerr << " " << (*vsit) << endl;
// the vertex must be removed from the _vertexes_to_route
// XXX Woowoo il ne faut pas faire un erase du vertex atteint, mais rechercher le représentant de la composante connexe atteinte dans les _vertexes_to_route et faire un erase dessus !
Vertex* toErase = NULL;
for ( VertexSetIter vsit = _vertexes_to_route.begin() ; vsit != _vertexes_to_route.end() ; vsit++ ) {
if ( (*vsit)->getConnexID() == currentConnexID )
toErase = (*vsit);
}
//cerr << " gonna erase : " << toErase << endl;
// on veut updater toute la composante connexe représenter par le currentVertex
#ifndef NDEBUG
unsigned deleteVertex = _vertexes_to_route.erase ( toErase );
assert ( deleteVertex == 1 );
#else
_vertexes_to_route.erase ( toErase );
#endif
// the connexe component corresponding to the vertex must be initialize with the firstConnexID
initConnexComp ( currentVertex, firstConnexID );
// create the new connex component and initializes it :
while ( Edge* predecessor = currentVertex->getPredecessor() ) {
currentVertex->setPredecessor ( NULL );
predecessor->setConnexID ( firstConnexID );
currentVertex = predecessor->getOpposite ( currentVertex );
// si jamais on réatteint un vertex dejà mis à jour.
if ( currentVertex->getConnexID() == firstConnexID )
break;
currentVertex->setDistance(0);
currentVertex->setConnexID(firstConnexID);
VTuple* vtuple = currentVertex->getVTuple();
if ( vtuple ) {
increaseVTuplePriority ( vtuple, 0);
}
else {
vtuple = VTuple::create ( currentVertex, 0 );
addVTupleToPriorityQueue ( vtuple );
}
}
//}
}
// VTuplePriorityQueue Utility Methods
// ***********************************
Vertex* Graph::extractMinFromPriorityQueue()
// *****************************************
{
if ( _vtuplePriorityQueue.begin() == _vtuplePriorityQueue.end() )
return NULL;
VTuple* vtuple = *(_vtuplePriorityQueue.begin());
Vertex* vertex = vtuple->getVertex();
_vtuplePriorityQueue.erase ( _vtuplePriorityQueue.begin() );
vtuple->destroy();
vertex->setVTuple ( NULL );
return vertex;
}
Vertex* Graph::getMinFromPriorityQueue()
// *************************************
{
if ( _vtuplePriorityQueue.begin() == _vtuplePriorityQueue.end() )
return NULL;
VTuple* vtuple = *(_vtuplePriorityQueue.begin());
Vertex* vertex = vtuple->getVertex();
return vertex;
}
void Graph::PopMinFromPriorityQueue()
// **********************************
{
if ( _vtuplePriorityQueue.begin() != _vtuplePriorityQueue.end() ) {
VTuple* vtuple = *(_vtuplePriorityQueue.begin());
Vertex* vertex = vtuple->getVertex();
_vtuplePriorityQueue.erase ( _vtuplePriorityQueue.begin() );
vtuple->destroy();
vertex->setVTuple ( NULL );
}
}
void Graph::addVTupleToPriorityQueue ( VTuple* vtuple )
// *************************************************
{
//cerr << "addVTupleToPriorityQueue: "
// << (void*)vtuple << " " << (void*)vtuple->getVertex() << ":" << vtuple->getVertex() << endl;
assert ( vtuple );
assert ( vtuple->getVertex()->getVTuple() == vtuple );
assert ( _vtuplePriorityQueue.find ( vtuple ) == _vtuplePriorityQueue.end() );
if (debugging)
cerr << " ADDING vtuple to priority queue : " << vtuple->_getString() << endl;
_vtuplePriorityQueue.insert ( vtuple );
//pair<VTuplePQIter,bool> p = _vtuplePriorityQueue.insert ( vtuple );
//assert ( p.second );
}
void Graph::increaseVTuplePriority ( VTuple* vtuple, float distance )
// ***************************************************************
{
assert ( vtuple );
//if ( debugging )
// cerr << " " << vtuple->getVertex() << " : " << vtuple->getDistance() << " > " << distance << endl;
assert ( vtuple->getDistance() > distance );
// Copy removeVTupleFromPriorityQueue without vtuple->destroy()
VTuplePQIter pqit = _vtuplePriorityQueue.find ( vtuple );
if ( pqit != _vtuplePriorityQueue.end() ) {
assert ( vtuple->getVertex() == (*pqit)->getVertex() );
_vtuplePriorityQueue.erase ( pqit );
}
// end copy
vtuple->setDistance ( distance );
_vtuplePriorityQueue.insert ( vtuple );
}
void Graph::printVTuplePriorityQueue()
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
// ***********************************
{
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
ltracein(600);
ltrace(600) << "VTuplePriorityQueue:" << endl;
unsigned int i=0;
for ( auto iv : _vtuplePriorityQueue ) {
ltrace(600) << setw(3) << i << "| " << iv->getVertex() << " : " << iv->getDistance() << endl;
++i;
}
ltraceout(600);
}
void Graph::clearPriorityQueue()
// *****************************
{
for ( VTuplePQIter pqit = _vtuplePriorityQueue.begin() ; pqit != _vtuplePriorityQueue.end() ; pqit++ ) {
(*pqit)->destroy();
}
_vtuplePriorityQueue.clear();
}
// STuplePriorityQueue Utility Methods
// ***********************************
Segment* Graph::extractMaxFromSTuplePQ()
// *************************************
{
if ( _stuplePriorityQueue.begin() == STuple::_stuplePQEnd )
return NULL;
STuple* stuple = *(_stuplePriorityQueue.begin());
Segment* segment = stuple->getSegment();
_stuplePriorityQueue.erase ( _stuplePriorityQueue.begin() );
stuple->destroy();
return segment;
}
STuple* Graph::getMaxFromSTuplePQ()
// ********************************
{
if ( _stuplePriorityQueue.begin() == STuple::_stuplePQEnd )
return NULL;
STuple* stuple = *(_stuplePriorityQueue.begin());
return stuple;
}
void Graph::popMaxFromSTuplePQ()
// *********************************
{
if ( _stuplePriorityQueue.begin() != STuple::_stuplePQEnd ) {
STuple* stuple = *(_stuplePriorityQueue.begin());
#ifndef NDEBUG
STuple::CostProperty* costProperty = stuple->getCostProperty();
assert ( costProperty );
assert ( (*costProperty->getPQIter()) == stuple );
#endif
stuple->destroy();
_stuplePriorityQueue.erase ( _stuplePriorityQueue.begin());
}
}
void Graph::addToSTuplePQ ( STuple* stuple )
// *****************************************
{
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
assert( stuple );
STuple::CostProperty* costProperty = stuple->getCostProperty();
assert( costProperty );
costProperty->setPQIter ( _stuplePriorityQueue.insert( stuple ) );
STuple::STuplePQIter pqit = costProperty->getPQIter();
assert( (*pqit) == stuple );
}
void Graph::updateSTupleCost ( STuple* stuple, unsigned cost )
// ***********************************************************
{
assert ( stuple );
STuple::CostProperty* costProperty = stuple->getCostProperty();
assert ( costProperty );
STuple::STuplePQIter pqit = costProperty->getPQIter();
assert ( (*pqit) == stuple );
_stuplePriorityQueue.erase ( pqit );
stuple->setCost ( cost );
costProperty->setPQIter ( _stuplePriorityQueue.insert ( stuple ) );
}
void Graph::printSTuplePQ()
// ************************
{
cmess1 << "*** printing STuplePriorityQueue ***" << endl;
STuple::STuplePQIter pqit = _stuplePriorityQueue.begin();
while ( pqit != STuple::_stuplePQEnd ) {
cmess1 << getString(*pqit) << endl;
pqit++;
}
cmess1 << "***********************************" << endl;
}
void Graph::clearSTuplePQ()
// ************************
{
for ( STuple::STuplePQIter pqit = _stuplePriorityQueue.begin() ; pqit != STuple::_stuplePQEnd ; pqit++ ) {
(*pqit)->destroy();
}
_stuplePriorityQueue.clear();
}
void Graph::testSTuplePQ()
// ***********************
{
// unsigned count = 0;
// Component* compo1 = NULL;
// Component* compo2 = NULL;
// for_each_component ( component, _nimbus->getCell()->getComponents() ) {
// if ( dynamic_cast<Segment*>(component) ) {
// STuple::CostProperty* costProperty = STuple::CostProperty::create (count );
// component->put ( costProperty );
// STuple* stuple = STuple::create ( costProperty );
// addToSTuplePQ ( stuple );
// if ( count == 4 ) compo1 = component;
// if ( count == 8 ) compo2 = component;
// count++;
// if ( count >= 10 )
// break;
// }
// end_for;
// }
// printSTuplePQ();
// STuple::CostProperty* costProperty = dynamic_cast<STuple::CostProperty*>(compo1->getProperty ( "Knik::CostProperty" ));
// updateSTupleCost ( (*costProperty->getPQIter()), 18 );
// cmess2 << "updateSTupleCost ( (*costProperty->getPQIter()), 18 )" << endl;
// printSTuplePQ();
// costProperty = dynamic_cast<STuple::CostProperty*>(compo2->getProperty ( "Knik::CostProperty"));
// updateSTupleCost ( (*costProperty->getPQIter()), 2 );
// cmess2 << "updateSTupleCost ( (*costProperty->getPQIter()), 2 )" << endl;
// printSTuplePQ();
// popMaxFromSTuplePQ();
// cmess2 << "popMaxFromSTuplePQ()" << endl;
// printSTuplePQ();
// cmess2 << "getString ( getMaxFromSTuplePQ() )" << endl;
// cmess2 << getString ( getMaxFromSTuplePQ() ) << endl;
// printSTuplePQ();
// cmess2 << "getString ( extractMaxFromSTuplePQ() )" << endl;
// cmess2 << getString ( extractMaxFromSTuplePQ() ) << endl;
// printSTuplePQ();
// clearSTuplePQ();
// cmess2 << "clearSTuplePQ()" << endl;
// printSTuplePQ();
}
int Graph::countVertexes ( Net* net )
// **********************************
{
assert ( net );
_working_net = net;
forEach ( Component*, component, net->getComponents() ) {
if ( RoutingPad* routingPad = dynamic_cast<RoutingPad*>(*component) ) {
//if ( routingPad->getCenter().getY() < 0 ) {
// CEditor* editor = getCEditor ( getCell() );
// editor->Select ( routingPad );
// editor->Refresh();
// editor->Stop ( "RoutingPad" );
// editor->Unselect( routingPad );
//}
Vertex* vertex = getVertex ( routingPad->getCenter() );
assert(vertex);
if ( _vertexes_to_route.find ( vertex ) == _vertexes_to_route.end() ) {
_vertexes_to_route.insert ( vertex );
}
}
}
return _vertexes_to_route.size();
}
int Graph::initRouting ( Net* net )
// ********************************
{
assert ( net );
_working_net = net;
//cerr << "[DEBUG]: Net: " << _working_net << endl;
//cerr << "[DEBUG]: vertexes_to_route size: " << _vertexes_to_route.size() << endl;
//CEditor* editor = getCEditor( _nimbus->getCell() );
//editor->Refresh();
//editor->Stop ("Going to init");
int currentConnexID = 0;
vector<Contact*> vContacts;
vector<RoutingPad*> vRoutingPads;
unsigned compoSize = net->getComponents().getSize();
vContacts.reserve ( compoSize );
vRoutingPads.reserve ( compoSize );
for_each_component ( component, net->getComponents() ) {
if ( dynamic_cast<RoutingPad*>(component) )
vRoutingPads.push_back ( static_cast<RoutingPad*>(component) );
if ( dynamic_cast<Contact*>(component) ) {
Contact* contact = static_cast<Contact*>(component);
if ( isAGlobalRoutingContact ( contact ) )
vContacts.push_back ( contact );
}
end_for;
}
//cerr << " vContacts size : " << vContacts.size() << endl;
//cerr << " vRoutingPads size : " << vRoutingPads.size() << endl;
UpdateSession::open();
for ( unsigned index = 0; index < vContacts.size() ; index++ ) {
Contact* contact = vContacts[index];
//cerr << " contact : " << contact << "" << endl;
Vertex* contactVertex = getVertex ( contact->getCenter() );
Contact* vContact = contactVertex->getContact();
if ( (vContact == contact) && (contactVertex->getNetStamp() == _netStamp) ) {
//cerr << " on a deja un contact associe avec le meme netStamp !" << endl;
continue; // on la déjà traité à travers le parcourt de composante connexe
}
else {
//cerr << " rebuild connexe component " << contact << "" << endl;
rebuildConnexComponent ( contact, currentConnexID, NULL );
//cerr << " done" << endl;
if ( _vertexes_to_route.find ( contactVertex ) == _vertexes_to_route.end() ) {
//cerr << " Adding vertex to _vertexes_to_route: continue" << endl;
_vertexes_to_route.insert ( contactVertex );
_searchingArea.merge ( contactVertex->getBox() );
contactVertex->setDistance((float)(HUGE_VAL));
contactVertex->setPredecessor(NULL);
currentConnexID++;
}
}
}
//cerr << " traitement pour les contacts : OK" << endl;
//OoOoooOoooOoO A QUOI SERT CE BOOLEEN OoOoooOoooOoO ==>> pour le //5 le connexID ne doit pas avoir été augmenté ! ou alors connexID-1 !!
//bool useConnexID = false;
for ( unsigned index = 0 ; index < vRoutingPads.size() ; index ++ ) {
RoutingPad* routingPad = vRoutingPads[index];
//cerr << " RoutingPad :" << routingPad << endl;
Vertex* rpVertex = getVertex ( routingPad->getCenter() );
//cerr << " Vertex :" << rpVertex << endl;
Contact* rpContact = rpVertex->getContact();
if ( rpContact && (rpContact->getNet() == routingPad->getNet()) ) {
// s'il existe deja un contact pour ce vertex pour ce net, on s'y attache
//cerr << " Contact already exists: attaching hooks" << endl;
// le contact a deja ete cree, il suffit d'ajouter le routingPad à la ronde du contact.
routingPad->getBodyHook()->detach();
routingPad->getBodyHook()->attach ( rpVertex->getContact()->getBodyHook() );
}
else {
// sinon on crée un contact et on s'y attache
Contact* contact = Contact::create ( _working_net
, DataBase::getDB()->getTechnology()->getLayer("metal2")
, rpVertex->getPosition().getX()
, rpVertex->getPosition().getY()
, rpVertex->getHalfWidth()/5
, rpVertex->getHalfHeight()/5
);
rpVertex->setContact ( contact );
routingPad->getBodyHook()->detach();
routingPad->getBodyHook()->attach ( contact->getBodyHook() );
if ( _vertexes_to_route.find ( rpVertex ) == _vertexes_to_route.end() ) {
//cerr << " Adding vertex to _vertexes_to_route: continue" << endl;
_vertexes_to_route.insert ( rpVertex );
_searchingArea.merge ( rpVertex->getBox() );
rpVertex->setConnexID ( currentConnexID );
rpVertex->setNetStamp ( _netStamp );
rpVertex->setDistance((float)(HUGE_VAL));
rpVertex->setPredecessor(NULL);
currentConnexID++;
}
}
}
// for ripup & reroute purpose
if ( __ripupMode__ )
_searchingArea = _cell->getAbutmentBox(); // recherche sur toute la surface : trop long pour gros circuits
//_searchingArea.inflate((_searchingArea.getWidth()*10)/100, (_searchingArea.getHeight()*10)/100); // raté ça ne marche pas avec les nets plats
//cerr << " traitement pour les routingPads : OK" << endl;
UpdateSession::close();
//cerr << "[DEBUG]: vertexes_to_route size (after init): " << _vertexes_to_route.size() << endl;
//editor->Refresh();
//editor->Stop("initDone");
// 8/10/2007
// {
// Expand seaching area
//int bottomLineIdx = (int)_matrixVertex->getLineIndex ( _searchingArea.getYMin() +1 );
//int topLineIdx = (int)_matrixVertex->getLineIndex ( _searchingArea.getYMax() -1 );
//int leftColumnIdx = (int)_matrixVertex->getColumnIndex ( _searchingArea.getXMin() +1 );
//int rightColumnIdx = (int)_matrixVertex->getColumnIndex ( _searchingArea.getXMax() -1 );
//if ( _matrixVertex->isLineIndexValid ( bottomLineIdx - 2 ) )
// bottomLineIdx -= 2;
//else if ( _matrixVertex->isLineIndexValid ( bottomLineIdx - 1 ) )
// bottomLineIdx -= 1;
//if ( _matrixVertex->isLineIndexValid ( topLineIdx + 2 ) )
// topLineIdx += 2;
//else if ( _matrixVertex->isLineIndexValid ( topLineIdx + 1 ) )
// topLineIdx += 1;
//if ( _matrixVertex->isColumnIndexValid ( leftColumnIdx - 2 ) )
// leftColumnIdx -= 2;
//else if ( _matrixVertex->isColumnIndexValid ( leftColumnIdx - 1 ) )
// leftColumnIdx -= 1;
//if ( _matrixVertex->isColumnIndexValid ( rightColumnIdx + 2 ) )
// rightColumnIdx += 2;
//else if ( _matrixVertex->isColumnIndexValid ( rightColumnIdx + 1 ) )
// rightColumnIdx += 1;
//_searchingArea.merge ( _matrixVertex->getVertexFromIndexes(bottomLineIdx, leftColumnIdx)->getGCell()->getBox() );
//_searchingArea.merge ( _matrixVertex->getVertexFromIndexes(topLineIdx, rightColumnIdx)->getGCell()->getBox() );
//cerr << "net " << net << " has " << _vertexes_to_route.size() << " vertexes to route." << endl;
//}
return _vertexes_to_route.size();
}
void Graph::Dijkstra()
// *******************
{
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
//checkEmptyPriorityQueue();
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
countDijkstra++;
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
// first we need to choose the closest to center vertex in _vertexes_to_route
Vertex* centralVertex = getCentralVertex();
//ltrace(435) << " most centered vertex is " << centralVertex << endl;
// we want to prepare all vertexes of the 'composante connexe'
// set the distance to 0
// insert each vertex in the vtuplePriorityQueue
initConnexComp( centralVertex );
// create a copy of _vertexes_to_route vector fo method UpdateEstimateCongestion
//set<Vertex*,VertexPositionComp> copy_vertex = _vertexes_to_route; // This is no more useful
//#if defined ( __USE_DYNAMIC_PRECONGESTION__ )
if ( !__ripupMode__ && (__precongestion__ == 2) )
UpdateEstimateCongestion();
//#endif
DebugSession::open( _working_net, 600 );
ltrace(600) << "Dijkstra for net: " << _working_net << endl;
ltracein(600);
ltrace(600) << "Stamp:" << _netStamp << endl;
ltrace(600) << "Central vertex : " << centralVertex << endl;
ltrace(600) << "_vertexes_to_route.size(): " << _vertexes_to_route.size() << endl;
ltracein(600);
//Breakpoint::stop(1, "<center><b>Dijkstra</b><br>initialized</center>");
while ( _vertexes_to_route.size() > 1 ) {
// Now, let's expanse the top of the queue
VertexList reachedVertexes;
float reachedDistance = (float)(HUGE_VAL);
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
//checkGraphConsistency();
if (ltracelevel() >= 600) {
ltrace(600) << "_vertexes_to_route:" << endl;
for ( auto iv : _vertexes_to_route )
ltrace(600) << "| " << iv << endl;
}
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
ltrace(600) << "Source component" << endl;
printVTuplePriorityQueue();
//Breakpoint::stop(1, "<center><b>Dijkstra</b><br>source connexe component</center>");
Vertex* firstVertex = getMinFromPriorityQueue();
assert( firstVertex );
Vertex* currentVertex = firstVertex;
int firstVertexConnex = firstVertex->getConnexID();
while ( currentVertex and (currentVertex->getDistance() < reachedDistance) ) {
PopMinFromPriorityQueue();
assert( not currentVertex->getVTuple() );
// IMPORTANT : each currentVertex considered here has been getFromPriorityQueue()
// which means its NetStamp and ConnexID are set for the current _working_net :
// no need to check netStamp
int currentVertexConnex = currentVertex->getConnexID() ;
if ( (currentVertexConnex != -1) and (currentVertexConnex != firstVertexConnex) ) {
reachedDistance = currentVertex->getDistance();
reachedVertexes.clear();
reachedVertexes.push_back ( currentVertex );
ltrace(600) << "Re-init reachedVertexes with " << currentVertex << endl;
break;
}
Edge* arrivalEdgeCurrentVertex = currentVertex->getPredecessor();
forEach ( Edge*, iedge, currentVertex->getAdjacentEdges() ) {
if ( (iedge->getNetStamp() == _netStamp) && (iedge->getConnexID() == firstVertexConnex) ) {
// already visited iedge
// ok because to reach a connex component the algorithm first reach a vertex !!
continue;
}
iedge->setConnexID(-1); // reinitialize connexID for edge (was done by CleanRoutingState)
iedge->setNetStamp(_netStamp);
Vertex* oppositeVertex = iedge->getOpposite ( currentVertex );
assert( oppositeVertex );
if (not _searchingArea.contains(oppositeVertex->getPosition()))
continue;
float newDistance = currentVertex->getDistance()
+ iedge->getCost( arrivalEdgeCurrentVertex );
bool updateOppositeVertex = false;
// reinitialize the oppositeVertex if its netStamp is < _netStamp
if (oppositeVertex->getNetStamp() < _netStamp) {
//oppositeVertex->setLocalRingHook(NULL);
oppositeVertex->setContact(NULL);
oppositeVertex->setConnexID(-1);
updateOppositeVertex = true;
}
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
int oppositeConnex = oppositeVertex->getConnexID();
float oppositeDistance = oppositeVertex->getDistance();
if ( updateOppositeVertex or (newDistance + EPSILON < oppositeDistance) ) {
assert( oppositeConnex != firstVertexConnex );
oppositeVertex->setPredecessor( *iedge );
oppositeVertex->setDistance ( newDistance );
oppositeVertex->setNetStamp ( _netStamp );
VTuple* oppositeVTuple = oppositeVertex->getVTuple();
if (oppositeVTuple) {
ltrace(600) << "Increasing priority for:" << endl;
ltrace(600) << "* " << oppositeVertex << endl;
ltrace(600) << "* " << oppositeVTuple << endl;
increaseVTuplePriority( oppositeVTuple, newDistance );
// Du fait de la reinit ce n'est plus seulement un increase!
// Non, c'est bon si on garde le CleanRoutingState (avec clearPriorityQueue)
} else {
VTuple* newOppositeVTuple = VTuple::create ( oppositeVertex, newDistance );
ltrace(600) << "Creating New VTuple for Vertex:" << endl;
ltrace(600) << "* " << oppositeVertex << ":" << newDistance << endl;
ltrace(600) << "* " << newOppositeVTuple << endl;
addVTupleToPriorityQueue( newOppositeVTuple );
}
ltrace(600) << "Updated distance " << newDistance << " on: " << (*iedge) << endl;
printVTuplePriorityQueue();
//Breakpoint::stop(1, "<center><b>Dijkstra</b><br>distance has been updated</center>");
}
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 ( (oppositeConnex != -1) and (oppositeConnex != firstVertexConnex) ) {
// verifier si la newDistance est inférieure a la reachedDistance,
// si oui vider la liste des reachedVertex et ajouter l'oppositeVertex
// si == ajouter l'oppositeVertex a la liste (a condition qu'il n'y soit pas déjà)
// si > rien a faire (a verifier que la pile de priorité se comporte bien)
if (newDistance < reachedDistance) {
reachedDistance = newDistance;
reachedVertexes.clear();
reachedVertexes.push_back( oppositeVertex );
ltrace(600) << "Re-init (< distance) reachedVertexes with " << oppositeVertex << endl;
} else if (newDistance == reachedDistance) {
// on pourrait simplifier grandement tout ca : 1 seul vertex atteint sauvergardé!
// Conclusion qu'il ait le meme connexID ou pas, on ne fait rien, on en a deja atteint
// un avec la meme distance ...
bool foundVertex = false;
for ( auto iv : reachedVertexes ) {
// the following test depends on the fact we authorize multiple representant (vertex)
// of the same connexe component in reachedVertexes list
//if (iv->getConnexID() == oppositeConnex)
if (iv == oppositeVertex) {
foundVertex = true;
break;
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
}
}
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 (not foundVertex) {
reachedVertexes.push_back( oppositeVertex );
ltrace(600) << "Re-init (== distance) reachedVertexes with " << oppositeVertex << endl;
}
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
} else {
// Nothing to 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
}
currentVertex = getMinFromPriorityQueue();
}
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 (reachedVertexes.empty()) {
ostringstream message;
message << "In Graph::Dijkstra():\n";
message << " Unable to reach target on net " << _working_net->getName() << ".";
throw Error( message.str() );
}
assert( reachedDistance < (float)(HUGE_VAL) );
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
ltrace(600) << "Updating two connex components:" << endl;
ltrace(600) << "1. " << (*(reachedVertexes.begin())) << endl;
ltrace(600) << "2. " << firstVertex << endl;
UpdateConnexComp( reachedVertexes, firstVertex );
}
//cerr << "check before materialize _vertexes_to_route.size = " << _vertexes_to_route.size() << endl;
//checkGraphConsistency();
MaterializeRouting ( *(_vertexes_to_route.begin()) );
//_vertexes_to_route.clear(); // no more useful
//_vertexes_to_route = copy_vertex ;
ltraceout(600);
ltraceout(600);
DebugSession::close();
}
void Graph::Monotonic()
// ********************
{
// This function execute an algorithm of monotonic routing
// it assumes that _vertexes_to_route.sze is 2 (only 2 pin nets can be route with monotonic routing)
assert ( _vertexes_to_route.size() == 2 );
countMonotonic++;
//cerr << "Monotonic for net " << _working_net << " : " << _netStamp << endl;
//cerr << " check start monotonic" << endl;
//checkGraphConsistency();
Vertex* source = (*_vertexes_to_route.begin());
Vertex* target = (*_vertexes_to_route.rbegin());
assert ( source != target );
DbU::Unit sourceX = source->getPosition().getX();
DbU::Unit targetX = target->getPosition().getX();
if ( sourceX > targetX ) {
Vertex* temp = source;
source = target;
target = temp;
}
else if ( sourceX == targetX ) {
if ( source->getPosition().getY() > target->getPosition().getY() ) {
Vertex* temp = source;
source = target;
target = temp;
}
}
// POUR SIMPLIFIER : PAS DE TRAITEMENT D'UN GRAPHE DE ROUTAGE IRREGULIER POUR L'INSTANT
sourceX = source->getPosition().getX();
targetX = target->getPosition().getX();
DbU::Unit sourceY = source->getPosition().getY();
DbU::Unit targetY = target->getPosition().getY();
source->setDistance ( 0 );
if ( sourceY <= targetY ) {
// 1st case : monotonic directions : top and right
// marquing all vertexes which y-coordinates are equal to sourceY
Vertex* predecessor = source;
Edge* rightEdge = predecessor->getHEdgeOut();
while ( rightEdge ) {
Vertex* currentVertex = rightEdge->getOpposite ( predecessor );
if ( currentVertex->getPosition().getX() <= targetX ) {
currentVertex->setDistance ( predecessor->getDistance() + rightEdge->getCost( predecessor->getPredecessor() ) );
currentVertex->setPredecessor ( rightEdge );
predecessor = currentVertex;
rightEdge = predecessor->getHEdgeOut();
}
else
break;
}
// marquing all vertexes which x-coordinates are equal to sourceX
predecessor = source;
Edge* topEdge = predecessor->getVEdgeOut();
while ( topEdge ) {
//while ( topEdge->getNextFrom() != NULL )
// topEdge = topEdge->getNextFrom();
Vertex* currentVertex = topEdge->getOpposite ( predecessor );
if ( currentVertex->getPosition().getY() <= targetY ) {
currentVertex->setDistance ( predecessor->getDistance() + topEdge->getCost( predecessor->getPredecessor() ) );
currentVertex->setPredecessor ( topEdge );
predecessor = currentVertex;
topEdge = predecessor->getVEdgeOut();
}
else
break;
}
// marquing all others vertexes by column
predecessor = source;
rightEdge = predecessor->getHEdgeOut();
while ( rightEdge ) {
Vertex* baseColumn = rightEdge->getOpposite ( predecessor );
if ( baseColumn->getPosition().getX() <= targetX ) {
Vertex* vertPred = baseColumn;
Edge* topEdge = vertPred->getVEdgeOut();
while ( topEdge ) {
Vertex* currentVertex = topEdge->getOpposite ( vertPred );
if ( currentVertex->getPosition().getY() <= targetY ) {
float vertDistance = (float)(HUGE_VAL);
float horzDistance = (float)(HUGE_VAL);
vertDistance = vertPred->getDistance() + topEdge->getCost ( vertPred->getPredecessor() );
Edge* leftEdge = currentVertex->getHEdgeIn();
if ( leftEdge ) {
Vertex* horzPred = leftEdge->getOpposite ( currentVertex );
horzDistance = horzPred->getDistance() + leftEdge->getCost ( horzPred->getPredecessor() );
}
if ( vertDistance < horzDistance ) {
currentVertex->setDistance ( vertDistance );
currentVertex->setPredecessor ( topEdge );
}
else {
currentVertex->setDistance ( horzDistance );
currentVertex->setPredecessor ( leftEdge );
}
vertPred = currentVertex;
topEdge = vertPred->getVEdgeOut();
}
else
break;
}
predecessor = baseColumn;
rightEdge = predecessor->getHEdgeOut();
}
else
break;
}
}
else {
// 2nd case : monotonic directions : down and right
// marquing all vertexes which y-coordinates are equal to sourceY
Vertex* predecessor = source;
Edge* rightEdge = predecessor->getHEdgeOut();
while ( rightEdge ) {
Vertex* currentVertex = rightEdge->getOpposite ( predecessor );
if ( currentVertex->getPosition().getX() <= targetX ) {
currentVertex->setDistance ( predecessor->getDistance() + rightEdge->getCost ( predecessor->getPredecessor() ) );
currentVertex->setPredecessor ( rightEdge );
predecessor = currentVertex;
rightEdge = predecessor->getHEdgeOut();
}
else
break;
}
// marquing all vertexes which x-coordinates are equal to sourceX
predecessor = source;
Edge* bottomEdge = predecessor->getVEdgeIn();
while ( bottomEdge ) {
//while ( topEdge->getNextFrom() != NULL )
// topEdge = topEdge->getNextFrom();
Vertex* currentVertex = bottomEdge->getOpposite ( predecessor );
if ( currentVertex->getPosition().getY() >= targetY ) {
currentVertex->setDistance ( predecessor->getDistance() + bottomEdge->getCost ( predecessor->getPredecessor() ) );
currentVertex->setPredecessor ( bottomEdge );
predecessor = currentVertex;
bottomEdge = predecessor->getVEdgeIn();
}
else
break;
}
// marquing all others vertexes by column
predecessor = source;
rightEdge = predecessor->getHEdgeOut();
while ( rightEdge ) {
Vertex* baseColumn = rightEdge->getOpposite ( predecessor );
if ( baseColumn->getPosition().getX() <= targetX ) {
Vertex* vertPred = baseColumn;
Edge* bottomEdge = vertPred->getVEdgeIn();
while ( bottomEdge ) {
Vertex* currentVertex = bottomEdge->getOpposite ( vertPred );
if ( currentVertex->getPosition().getY() >= targetY ) {
float vertDistance = (float)(HUGE_VAL);
float horzDistance = (float)(HUGE_VAL);
vertDistance = vertPred->getDistance() + bottomEdge->getCost ( vertPred->getPredecessor() );
Edge* leftEdge = currentVertex->getHEdgeIn();
if ( leftEdge ) {
Vertex* horzPred = leftEdge->getOpposite ( currentVertex );
horzDistance = horzPred->getDistance() + leftEdge->getCost (horzPred->getPredecessor() );
}
if ( vertDistance < horzDistance ) {
currentVertex->setDistance ( vertDistance );
currentVertex->setPredecessor ( bottomEdge );
}
else {
currentVertex->setDistance ( horzDistance );
currentVertex->setPredecessor ( leftEdge );
}
vertPred = currentVertex;
bottomEdge = vertPred->getVEdgeIn();
if (!bottomEdge)
break;
currentVertex = bottomEdge->getOpposite ( vertPred );
}
else
break;
}
predecessor = baseColumn;
rightEdge = predecessor->getHEdgeOut();
}
else
break;
}
}
// On crée la nouvelle composante connexe à partir du chemin monotone trouvé :
int sourceID = source->getConnexID();
Vertex* currentVertex = target;
while ( Edge* predecessor = currentVertex->getPredecessor() ) {
currentVertex->setConnexID ( sourceID );
currentVertex->setNetStamp ( _netStamp );
predecessor->setConnexID ( sourceID );
predecessor->setNetStamp ( _netStamp );
currentVertex = predecessor->getOpposite ( currentVertex );
}
source->setNetStamp ( _netStamp );
assert ( currentVertex == source );
MaterializeRouting ( source );
//#if defined ( __USE_DYNAMIC_PRECONGESTION__ )
if ( __precongestion__ == 2 )
UpdateEstimateCongestion();
//#endif
}
FTree* Graph::createFluteTree()
// ****************************
{
int accuracy = 3; // accuracy for flute (by default 3)
int d = _vertexes_to_route.size(); // degre du net, ie nombre de routingPads
int *x = new int [d]; // x coordinates of the vertexes
int *y = new int [d]; // y coordinates of the vertexes
FTree* flutetree = new FTree; // the flute Steiner Tree
//cout << "Net : " << _working_net << endl;
// scans _working_net to find x,y coordinates and fill x, y and d
// parcours des _vertexes_to_route
VertexSetIter vsit = _vertexes_to_route.begin();
int cpt = 0;
while ( vsit != _vertexes_to_route.end() ) {
Point position = (*vsit)->getPosition();
x[cpt] = position.getX();
y[cpt] = position.getY();
vsit++;
cpt++;
}
assert ( d == cpt );
*flutetree = flute ( d, x, y, accuracy );
//printtree ( flutetree );
//plottree ( flutetree );
//cout << endl;
return flutetree;
}
void Graph::UpdateEstimateCongestion ( bool create )
// *************************************************
{
if ( _vertexes_to_route.size() < 2 )
return;
if ( _vertexes_to_route.size() >= FLUTE_LIMIT ) {
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 ( create )
cerr << Warning( "Graph::UpdateEstimateCongestion(): %s\n"
" has more than %d vertex/terminals and cannot be handled by FLUTE."
, getString(_working_net).c_str(), FLUTE_LIMIT ) << endl;
return;
}
//cerr << "Running FLUTE for net : " << _working_net << endl;
auto_ptr<FTree> flutetree ( createFluteTree() );
//parcours des branches du FTree pour créer la congestion estimée
for ( int i = 0 ; i < 2*flutetree->deg-2 ; i++ ) {
// int sourceX = flutetree->branch[i].x;
// int sourceY = flutetree->branch[i].y;
// int targetX = flutetree->branch[flutetree->branch[i].n].x;
// int targetY = flutetree->branch[flutetree->branch[i].n].y;
Vertex* source = getVertex ( flutetree->branch[i].x , flutetree->branch[i].y );
Vertex* target = getVertex ( flutetree->branch[flutetree->branch[i].n].x, flutetree->branch[flutetree->branch[i].n].y );
assert ( source );
assert ( target );
//Si source et target alignée -> ajoute 1 a toutes les edges sur le chemin
if ( source->isVerticallyAligned ( target ) ) {
sortVVertexes ( source, target );
Vertex* currentVertex = source;
while ( currentVertex != target ) {
Edge* edge = currentVertex->getVEdgeOut();
assert ( edge );
edge->addSubEstimateOccupancy ( 1.0, create );
currentVertex = edge->getOpposite ( currentVertex );
assert ( currentVertex );
}
}
else if ( source->isHorizontallyAligned ( target ) ) {
sortHVertexes ( source, target );
Vertex* currentVertex = source;
while( currentVertex != target ) {
Edge* edge = currentVertex->getHEdgeOut();
assert ( edge );
edge->addSubEstimateOccupancy ( 1.0, create );
currentVertex = edge->getOpposite ( currentVertex );
assert ( currentVertex );
}
}
else {
sortHVertexes ( source, target );
if ( source->getY() < target->getY() ) {
// 1st case :
// +-------T +-------T T
// | | | |
// | | = | 0.5 + 0.5 |
// | | | |
// S-------+ S S-------+
Vertex* currentVertex = source;
while ( currentVertex->getY() < target->getY() ) {
Edge* edge = currentVertex->getVEdgeOut();
// assert ( edge );
edge->addSubEstimateOccupancy ( 0.5, create );
currentVertex = edge->getOpposite ( currentVertex );
// assert ( currentVertex );
}
while ( currentVertex != target ) {
Edge* edge = currentVertex->getHEdgeOut();
// assert ( edge );
edge->addSubEstimateOccupancy ( 0.5, create );
currentVertex = edge->getOpposite ( currentVertex );
// assert ( currentVertex );
}
currentVertex = source;
while ( currentVertex->getX() < target->getX() ) {
Edge* edge = currentVertex->getHEdgeOut();
// assert ( edge );
edge->addSubEstimateOccupancy ( 0.5, create );
currentVertex = edge->getOpposite ( currentVertex );
// assert ( currentVertex );
}
while ( currentVertex != target ) {
Edge* edge = currentVertex->getVEdgeOut();
// assert ( edge );
edge->addSubEstimateOccupancy ( 0.5, create );
currentVertex = edge->getOpposite ( currentVertex );
// assert ( edge );
}
}
else {
// 2nd case :
// S-------+ S S-------+
// | | | |
// | | = | 0.5 + 0.5 |
// | | | |
// +-------T +-------T T
Vertex* currentVertex = source;
while ( currentVertex->getY() > target->getY() ) {
Edge* edge = currentVertex->getVEdgeIn();
// assert ( edge );
edge->addSubEstimateOccupancy ( 0.5, create );
currentVertex = edge->getOpposite ( currentVertex );
// assert ( currentVertex );
}
while ( currentVertex != target ) {
Edge* edge = currentVertex->getHEdgeOut();
// assert ( edge );
edge->addSubEstimateOccupancy ( 0.5, create );
currentVertex = edge->getOpposite ( currentVertex );
// assert ( currentVertex );
}
currentVertex = source;
while ( currentVertex->getX() < target->getX() ) {
Edge* edge = currentVertex->getHEdgeOut();
// assert ( edge );
edge->addSubEstimateOccupancy ( 0.5, create );
currentVertex = edge->getOpposite ( currentVertex );
// assert ( currentVertex );
}
while ( currentVertex != target ) {
Edge* edge = currentVertex->getVEdgeIn();
// assert ( edge );
edge->addSubEstimateOccupancy ( 0.5, create );
currentVertex = edge->getOpposite ( currentVertex );
// assert ( edge );
}
}
}
}
}
void Graph::UpdateMaxEstimateCongestion()
// **************************************
{
Vertex* currentVertex = _lowerLeftVertex;
while ( currentVertex ) {
Vertex* firstLineVertex = currentVertex;
while ( currentVertex ) {
Edge* hEdgeOut = currentVertex->getHEdgeOut();
unsigned max = 0;
float maxEsti = 0.0;
if ( hEdgeOut ) {
unsigned maxX = hEdgeOut->getRealOccupancy();
float maxXEsti = hEdgeOut->getEstimateOccupancy();
max += maxX;
maxEsti += maxXEsti;
if ( maxX > _maxXOccupancy )
_maxXOccupancy = maxX;
if ( maxXEsti > _maxXEstimateOccupancy )
_maxXEstimateOccupancy = maxXEsti;
}
Edge* vEdgeOut = currentVertex->getVEdgeOut();
if ( vEdgeOut ) {
unsigned maxY = vEdgeOut->getRealOccupancy();
float maxYEsti = vEdgeOut->getEstimateOccupancy();
max += maxY;
maxEsti += maxYEsti;
if ( maxY > _maxYOccupancy )
_maxYOccupancy = maxY;
if ( maxYEsti > _maxYEstimateOccupancy )
_maxYEstimateOccupancy = maxYEsti;
}
if ( max > _maxOccupancy )
_maxOccupancy = max;
if ( maxEsti > _maxEstimateOccupancy )
_maxEstimateOccupancy = maxEsti;
if ( hEdgeOut )
currentVertex = hEdgeOut->getOpposite ( currentVertex );
else
break;
}
Edge* vEdgeOut = firstLineVertex->getVEdgeOut();
if ( vEdgeOut )
currentVertex = vEdgeOut->getOpposite ( firstLineVertex );
else
break;
}
}
Edge* Graph::getEdge ( unsigned col1, unsigned row1, unsigned col2, unsigned row2 )
// ********************************************************************************
{
Edge* edge = NULL;
if ( col1 == col2 ) {
if ( row1 == row2 )
throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be different." );
Vertex* bottomVertex = NULL;
Vertex* topVertex = NULL;
if ( ( row1 < row2 ) && ( row2 == row1 + 1 ) ) {
bottomVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row1) );
topVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row2) );
} else if ( row1 == row2 + 1 ) {
bottomVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row2) );
topVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row1) );
} else
throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be contiguous." );
edge = bottomVertex->getVEdgeOut();
assert ( edge->getOpposite(bottomVertex) == topVertex );
} else if ( row1 == row2 ) {
Vertex* leftVertex = NULL;
Vertex* rightVertex = NULL;
if ( ( col1 < col2 ) && ( col2 == col1 + 1 ) ) {
leftVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row1) );
rightVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col2, row1) );
} else if ( col1 == col2 + 1 ) {
leftVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col2, row1) );
rightVertex = _matrixVertex->getVertex ( pair<unsigned int, unsigned int>(col1, row1) );
} else
throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be contiguous." );
edge = leftVertex->getHEdgeOut();
assert ( edge->getOpposite(leftVertex) == rightVertex );
} else
throw Error ( "Graph::UpdateEdgeCapacity(): the two specified vertices must be vertically or horizontally aligned." );
return edge;
}
void Graph::UpdateEdgeCapacity ( unsigned col1, unsigned row1, unsigned col2, unsigned row2, unsigned cap )
// ********************************************************************************************************
{
getEdge ( col1, row1, col2, row2 )->setCapacity ( cap );
}
void Graph::increaseEdgeCapacity ( unsigned col1, unsigned row1, unsigned col2, unsigned row2, int cap )
// *****************************************************************************************************
{
getEdge ( col1, row1, col2, row2 )->increaseCapacity ( cap );
}
void Graph::updateEdgesOccupancy ( Segment* segment, bool add )
// ************************************************************
{
if ( Horizontal* horiz = dynamic_cast<Horizontal*>(segment) ) {
Vertex* currentVertex = _matrixVertex->getVertex ( Point ( horiz->getSourceX(), horiz->getY() ) );
Vertex* targetVertex = _matrixVertex->getVertex ( Point ( horiz->getTargetX(), horiz->getY() ) );
while ( currentVertex != targetVertex ) {
Edge* edge = currentVertex->getHEdgeOut();
assert ( edge );
if ( add )
edge->insertSegment ( segment );
else
edge->removeSegment ( segment );
currentVertex = edge->getOpposite ( currentVertex );
assert ( currentVertex );
}
}
else if ( Vertical* verti = dynamic_cast<Vertical*>(segment) ) {
Vertex* currentVertex = _matrixVertex->getVertex ( Point ( verti->getX(), verti->getSourceY() ) );
Vertex* targetVertex = _matrixVertex->getVertex ( Point ( verti->getX(), verti->getTargetY() ) );
while ( currentVertex != targetVertex ) {
Edge* edge = currentVertex->getVEdgeOut();
assert ( edge );
if ( add )
edge->insertSegment ( segment );
else
edge->removeSegment ( segment );
currentVertex = edge->getOpposite ( currentVertex );
assert ( currentVertex );
}
}
}
void Graph::rebuildConnexComponent ( Contact* contact, int connexID, Segment* arrivalSegment )
// *******************************************************************************************
{
//CEditor* editor = getCEditor ( _nimbus->getCell() );
Vertex* contactVertex = getVertex ( contact->getCenter() );
contactVertex->setContact ( contact );
contactVertex->setConnexID ( connexID );
contactVertex->setNetStamp ( _netStamp );
contactVertex->setDistance((float)(HUGE_VAL));
contactVertex->setPredecessor(NULL);
//cerr << "from :" << contact << endl;
//cerr << "arrivalSegment: " << arrivalSegment << endl;
for_each_component ( component, contact->getSlaveComponents() ) {
if ( dynamic_cast<Segment*>(component) ) {
Segment* segment = static_cast<Segment*>(component);
//cerr << " a segment " << segment << endl;
//editor->Stop("Guess what to do");
if ( segment == arrivalSegment ) continue;
//cerr << " not arrivalSegment -> setNetStampConnexID" << endl;
setNetStampConnexID ( segment, connexID );
//cerr << " done" << endl;
if ( !dynamic_cast<Contact*>( segment->getOppositeAnchor(contact) ) )
throw Error ("Graph::rebuildConnexComponent(): For the moment we do not consider Segments that anchors on something else than a Contact.");
Contact* oppositeContact = static_cast<Contact*>(segment->getOppositeAnchor(contact));
//cerr << " now recursive call on oppositeContact: " << oppositeContact << endl;
//editor->Stop("See what has been done");
rebuildConnexComponent ( oppositeContact, connexID, segment );
//cerr << " done" << endl;
}
end_for;
}
}
void Graph::setNetStampConnexID ( Segment* segment, int connexID )
// ***************************************************************
{
unsigned int sourceColumnIdx = _matrixVertex->getColumnIndex ( segment->getSourceX() );
unsigned int sourceLineIdx = _matrixVertex->getLineIndex ( segment->getSourceY() );
unsigned int targetColumnIdx = _matrixVertex->getColumnIndex ( segment->getTargetX() );
unsigned int targetLineIdx = _matrixVertex->getLineIndex ( segment->getTargetY() );
if ( sourceColumnIdx == targetColumnIdx ) { // vertical segment
for ( unsigned line = sourceLineIdx ; line < targetLineIdx ; line++ ) {
Vertex* vertex = _matrixVertex->getVertexFromIndexes ( line, sourceColumnIdx );
assert(vertex);
vertex->setNetStamp ( _netStamp );
vertex->setConnexID ( connexID );
vertex->setDistance((float)(HUGE_VAL));
Edge* edge = vertex->getVEdgeOut();
assert(edge);
edge->setNetStamp ( _netStamp );
edge->setConnexID ( connexID );
}
Vertex* vertex = _matrixVertex->getVertexFromIndexes ( targetLineIdx, targetColumnIdx );
assert(vertex);
vertex->setNetStamp ( _netStamp );
vertex->setConnexID ( connexID );
vertex->setDistance((float)(HUGE_VAL));
return;
}
if ( sourceLineIdx == targetLineIdx ) { // horizontal segment
for ( unsigned column = sourceColumnIdx ; column < targetColumnIdx ; column++ ) {
Vertex* vertex = _matrixVertex->getVertexFromIndexes ( sourceLineIdx, column );
assert(vertex);
vertex->setNetStamp ( _netStamp );
vertex->setConnexID ( connexID );
vertex->setDistance((float)(HUGE_VAL));
Edge* edge = vertex->getHEdgeOut();
assert(edge);
edge->setNetStamp ( _netStamp );
edge->setConnexID ( connexID );
}
Vertex* vertex = _matrixVertex->getVertexFromIndexes ( targetLineIdx, targetColumnIdx );
assert(vertex);
vertex->setNetStamp ( _netStamp );
vertex->setConnexID ( connexID );
vertex->setDistance((float)(HUGE_VAL));
return;
}
throw Error ( "Graph::setNetStampConnexId(): what sort of segment is that, a diagonal one?" );
}
void Graph::insertSegment ( Segment* segment )
// *******************************************
{
updateEdgesOccupancy ( segment, true );
}
void Graph::removeSegment ( Segment* segment )
// *******************************************
{
updateEdgesOccupancy ( segment, false );
}
float Graph::getSegmentCost ( Segment* segment )
// *********************************************
{
unsigned nbDep = 0;
unsigned nbTot = 0;
unsigned sumDep = 0;
Vertex* currentVertex = getVertex ( segment->getSourcePosition() );
Vertex* targetVertex = getVertex ( segment->getTargetPosition() );
if ( segment->getSourceY() == segment->getTargetY() ) { // which means : if it's a horizontal segment
while ( currentVertex != targetVertex ) { // attention pour faire simple on code pour un grpahe regulier
Edge* edge = currentVertex->getHEdgeOut(); // il faudrait choisir la bonne HEdgeOut pour un graphe irregulier
unsigned ov = edge->getOverflow();
if ( ov ) {
nbDep++;
sumDep += ov;
}
nbTot++;
currentVertex = edge->getOpposite ( currentVertex );
}
}
else {
while ( currentVertex != targetVertex ) {
Edge* edge = currentVertex->getVEdgeOut();
unsigned ov = edge->getOverflow();
if ( ov ) {
nbDep++;
sumDep += ov;
}
nbTot++;
currentVertex = edge->getOpposite ( currentVertex );
}
}
if ( !nbTot )
return 0;
return (float(nbDep)/float(nbTot))*sumDep;
}
unsigned Graph::analyseRouting ( set<Segment*>& segmentsToUnroute )
// ****************************************************************
{
// This function construct the list of segments that participate to congestion
// empty Priority queue : easier than update each semgent when removing a semgent ...
clearSTuplePQ();
// 30/01/09 on remplace le parcours des nets/segments par un parcours des
// edges avec un map trié sur pointeur de segments et définissant un record:
// nbDep nBTot + sumOv pour chaque segment.
unsigned nbEdgesTot = 0;
unsigned nbEdgesOv = 0;
unsigned overflow = 0;
unsigned maxOv = 0;
unsigned wirelength = 0;
unsigned viaWirelength = 0;
map<Segment*, segmentStat> segmentsMap;
for ( unsigned i = 0 ; i < _all_edges.size() ; i++ )
{
Edge* edge = _all_edges[i];
nbEdgesTot++;
if ( edge->isCongested() ) {
nbEdgesOv++;
unsigned edgeOv = 2*edge->getOverflow();
overflow += edgeOv;
maxOv = edgeOv > maxOv ? edgeOv : maxOv;
edge->addSubEstimateOccupancy ( HISTORIC_INC, true ); // add historic cost for each overflowed edge
}
forEach ( Segment*, segment, edge->getSegments() ) {
map<Segment*, segmentStat>::iterator it = segmentsMap.find(*segment);
if ( it != segmentsMap.end() ) {
(*it).second.incNbTot();
if ( edge->isCongested() ) {
(*it).second.incNbDep();
(*it).second.incSumOv(edge->getOverflow());
}
}
else {
if ( edge->isCongested() )
segmentsMap[*segment]=segmentStat(1,1,edge->getOverflow());
else
segmentsMap[*segment]=segmentStat(0,1,0);
}
}
}
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
unsigned nbDep = 0;
unsigned nbTot = 0;
float minimalCost = 0;
float maximalCost = 0;
for ( map<Segment*, segmentStat>::iterator it = segmentsMap.begin() ; it != segmentsMap.end() ; it++ ) {
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
assert( (*it).second.getNbTot() != 0 );
nbTot++;
wirelength += getGridLength( (*it).first );
float segmentCost = (float((*it).second.getNbDep()) / float((*it).second.getNbTot())) * (*it).second.getSumOv();
if ( segmentCost ) {
if (minimalCost == 0)
minimalCost = segmentCost;
minimalCost = segmentCost < minimalCost ? segmentCost : minimalCost;
maximalCost = segmentCost > maximalCost ? segmentCost : maximalCost;
STuple* stuple = STuple::create((*it).first, segmentCost);
addToSTuplePQ(stuple);
nbDep++;
}
}
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
forEach ( Net*, net, _cell->getNets() ) {
forEach ( Contact*, contact, net->getContacts() ) {
const Layer* cLayer = contact->getLayer();
if ( cLayer == Configuration::getGContact() || cLayer == Configuration::getGMetalV() )
viaWirelength += 3;
}
}
//forEach ( Net*, net, _cell->getNets() ) {
// forEach ( Segment*, segment, net->getSegments() ) {
// if ( isAGlobalRoutingSegment ( *segment ) ) {
// float segmentCost = getSegmentCost ( *segment );
// if ( segmentCost ) {
// nbDep++;
// STuple* stuple = NULL;
// // si une CostProperty est attaché au segment et que son iterateur est différent de _stuplePQEnd
// // on recupere le STuple
// // sinon on cree un stuple
// Hurricane::Property* property = segment->getProperty ( STuple::CostProperty::_name );
// if ( STuple::CostProperty* cprop = dynamic_cast<STuple::CostProperty*>(property) ) {
// STuple::STuplePQIter pqit = cprop->getPQIter();
// if ( pqit != STuple::_stuplePQEnd )
// stuple = (*pqit);
// }
// if ( !stuple )
// stuple = STuple::create ( *segment, segmentCost );
// addToSTuplePQ ( stuple );
// }
// nbTot++;
// }
// }
//}
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
cmess2 << " # of Overcapacity edges:" << nbEdgesOv
<< " (tot.:" << nbEdgesTot << ")" << endl;
cmess2 << " # of Overflow:" << overflow
<< " Max. overflow:" << maxOv
<< " Avg. overflow:" << (float)overflow / (float)nbEdgesTot << endl;
cmess2 << " # of Overflowed edges: " << nbDep << " (tot.:" << nbTot << ")" << endl;
cmess2 << " gHPWL:" << wirelength
<< " # of VIAs:" << viaWirelength/3
<< " Tot. wirelength:" << wirelength + viaWirelength << endl;
// cmess1 << " o Analyse routing :" << endl
// << " - Number of overcapacity edges : " << nbEdgesOv << " / " << nbEdgesTot << endl
// << " - # of overflow : " << overflow << endl
// << " - max of overflow : " << maxOv << endl
// << " - avg overflow : " << (float)overflow / (float)nbEdgesTot << endl
// << " - grid wirelength : " << wirelength << endl
// << " - # of via : " << viaWirelength/3 << endl
// << " - total wirelength : " << wirelength + viaWirelength << endl
// << " - Overflowed segments : " << nbDep << " / " << nbTot << endl;
// construct the list on segments to unroute
if ( _stuplePriorityQueue.empty() ) {
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
//cmess1 << " - Nothing to reroute !" << endl;
//cmess1 << " - Maximum segment cost : 0" << endl;
}
else {
STuple* topSTuple = getMaxFromSTuplePQ();
float maxCost = topSTuple->getCost();
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
//cmess1 << " - Maximum segment cost : " << maxCost << endl;
float minCost = 0.20;
if (_stuplePriorityQueue.size() <= 100)
minCost = 0.0;
//if ( maxCost > 1 )
// minCost = maxCost * 0.20;
//cmess1 << " - Minimum segment cost considered : " << minCost << endl;
//cmess1 << " - Minimal computed segment cost : " << minimalCost << endl
// << " - Maximal computed segment cost : " << maximalCost << endl;
segmentsToUnroute.insert ( topSTuple->getSegment() );
//debugName = topSTuple->getSegment()->getNet()->getName();
popMaxFromSTuplePQ();
topSTuple = getMaxFromSTuplePQ();
//bool fullSkim = true;
//printSTuplePQ();
while ( topSTuple != NULL ) {
if ( topSTuple->getCost() >= minCost ) {
segmentsToUnroute.insert ( topSTuple->getSegment() );
popMaxFromSTuplePQ();
topSTuple = getMaxFromSTuplePQ();
}
else {
//fullSkim = false;
break;
}
}
//cerr << " - fullSkim : " << fullSkim << endl;
//printSTuplePQ();
}
return overflow;
}
void Graph::getHorizontalCutLines ( vector<DbU::Unit>& horizontalCutLines )
// ************************************************************************
{
horizontalCutLines.clear();
Vertex* currentVertex = _lowerLeftVertex;
horizontalCutLines.push_back ( currentVertex->getYMin() );
while ( currentVertex ) {
horizontalCutLines.push_back ( currentVertex->getYMax() );
Edge* edge = currentVertex->getVEdgeOut();
if ( edge )
currentVertex = edge->getTo();
else
break;
}
}
void Graph::getVerticalCutLines ( vector<DbU::Unit>& verticalCutLines )
// ********************************************************************
{
verticalCutLines.clear();
Vertex* currentVertex = _lowerLeftVertex;
verticalCutLines.push_back ( currentVertex->getXMin() );
while ( currentVertex ) {
verticalCutLines.push_back ( currentVertex->getXMax() );
Edge* edge = currentVertex->getHEdgeOut();
if ( edge)
currentVertex = edge->getTo();
else
break;
}
}
bool Graph::hasGlobalRouting ( RoutingPad* routingPad )
// ****************************************************
{
Hook* rpHook = routingPad->getBodyHook();
Vertex* rpVertex = _matrixVertex->getVertex ( routingPad->getX(), routingPad->getY() );
Hook* currentHook = rpHook->getNextHook();
while ( currentHook != rpHook ) {
if ( dynamic_cast<Segment::TargetHook*>(currentHook) ) {
Segment* seg = dynamic_cast<Segment*>(currentHook->getComponent());
if ( getVertex ( seg->getTargetX(), seg->getTargetY() ) == rpVertex )
return true;
}
if ( dynamic_cast<Segment::SourceHook*>(currentHook) ) {
Segment* seg = dynamic_cast<Segment*>(currentHook->getComponent());
if ( getVertex ( seg->getSourceX(), seg->getSourceY() ) == rpVertex )
return true;
}
currentHook = currentHook->getNextHook();
}
return false;
}
bool Graph::isAGlobalRoutingContact ( Contact* contact )
// *****************************************************
{
if ( contact->getLayer() == Configuration::getGMetalH () ) return true;
if ( contact->getLayer() == Configuration::getGMetalV () ) return true;
if ( contact->getLayer() == Configuration::getGContact() ) return true;
return false;
}
bool Graph::isAGlobalRoutingSegment ( Segment* segment )
// *****************************************************
{
if ( segment->getLayer() == Configuration::getGMetalH () ) return true;
if ( segment->getLayer() == Configuration::getGMetalV () ) return true;
return false;
}
static void setContactLayer(Contact* contact)
// ******************************************
{
bool alu2Used = false;
bool alu3Used = false;
for_each_hook(hook, contact->getBodyHook()->getHooks()) {
Component* component = hook->getComponent();
if (dynamic_cast<Segment*>(component) || dynamic_cast<RoutingPad*>(component)) {
const Layer* layer = component->getLayer();
if (layer == Configuration::getGMetalH() || layer == Configuration::getPinMetal() ) alu2Used = true;
else if (layer == Configuration::getGMetalV() ) alu3Used = true;
//else assert(false); // makes non ispd07 benchs failed....
}
end_for;
}
const Layer* layer = NULL;
if ( alu2Used ) {
if ( alu3Used )
layer = Configuration::getGContact();
else
layer = Configuration::getGMetalH();
}
else if ( alu3Used ) {
layer = Configuration::getGMetalV();
}
else
assert ( false );
contact->setLayer(layer);
}
void Graph::MaterializeRouting ( Vertex* vertex )
// **********************************************
{
// This function materializes the routing of the connexe component passed as argument
countMaterialize++;
//if ( debugging ) {
// cerr << " Materialize routing" << endl;
// CEditor* editor = getCEditor( _nimbus->getCell() );
// editor->Refresh();
// string stopMessage = "MaterializeRouting, starting vertex: ";
// stopMessage += getString ( vertex );
// editor->Stop(stopMessage);
//}
depthMaterialize = 0;
//cerr << "INITIAL CALL of materialize routing for net : " << _working_net << endl;
Edge* arrivalEdge = NULL;
Contact* initContact = NULL;
if ( _useSegments ) {
initContact = vertex->getContact ( arrivalEdge );
assert ( initContact ); // must be != NULL because the source vertex must have a routingPad !
}
MaterializeRouting ( vertex, arrivalEdge, initContact );
}
void Graph::MaterializeRouting ( Vertex* vertex, Edge* arrivalEdge, Contact* initialContact )
// ******************************************************************************************
{
depthMaterialize++;
int vertexConnex = vertex->getConnexID();
assert ( vertexConnex != -1 );
//cerr << "--> check in MaterializeRouting " << endl;
//checkGraphConsistency();
//cerr << " MR:" << depthMaterialize << ": vertex " << vertex << endl;
//add for test ofnew MaterializeRouting 03/09/2997 d2
if ( _useSegments ) {
for ( unsigned i = 0 ; i < 4 ; i++ ) {
if ( Edge* edge = vertex->getFirstEdges ( i ) ) {
if ( edge == arrivalEdge )
continue;
if ( (edge->getNetStamp() == _netStamp) && (edge->getConnexID() == vertexConnex) ) {
Vertex* oppositeVertex = edge->getOpposite ( vertex );
Contact* reachedContact = oppositeVertex->getContact(edge);
Edge* straightArrivalEdge = edge;
vector<Edge*> crossedEdges;
crossedEdges.push_back(edge);
while ( reachedContact == NULL ) {
straightArrivalEdge = oppositeVertex->getFirstEdges(i);
if ( straightArrivalEdge == NULL )
throw Error ( "Graph:MaterializeRouting(): Cannot continue straight on." );
oppositeVertex = straightArrivalEdge->getOpposite ( oppositeVertex );
reachedContact = oppositeVertex->getContact ( straightArrivalEdge );
//straightArrivalEdge->incOccupancy(); // put the incOccupancy in insertSegment function
crossedEdges.push_back(straightArrivalEdge);
}
// test pour ne pas recreer le routage preexistant en cas de reroutage
bool alreadyExist = false;
for_each_component ( component, initialContact->getSlaveComponents() ) {
if ( dynamic_cast<Segment*>(component) ) {
Segment* seg = static_cast<Segment*>(component);
if ( seg->getOppositeAnchor(initialContact) == (Component*)(reachedContact) ) {
//cerr << " segment already exists" << endl;
alreadyExist = true;
}
}
end_for;
}
if ( !alreadyExist ) {
Segment* segment = createSegment ( initialContact, reachedContact );
assert ( segment );
for ( unsigned j = 0 ; j < crossedEdges.size(); j++ )
crossedEdges[j]->insertSegment(segment);
}
MaterializeRouting ( oppositeVertex, straightArrivalEdge, reachedContact );
}
}
}
setContactLayer(initialContact);
}
//else {
// for_each_edge ( edge, vertex->getAdjacentEdges() ) {
// //if ( edge == arrivalEdge)
// // continue;
// //cerr << " MR:" << depthMaterialize<< ": edge " << edge << endl;
// if ( (edge->getNetStamp() == _netStamp) && (edge->getConnexID() == vertexConnex) ) {
// edge->createSplitter ( _working_net );
// _nbSplitters++;
// Hook* hook = edge->getSplitterHook ( vertex );
// assert (hook);
// if ( Hook* previousHook = vertex->getLocalRingHook() ) // XXX Attention puisqu'on vire le systeme le localRingHook au profit du contact
// hook->attach ( previousHook );
// vertex->setLocalRingHook ( hook );
// if ( edge != arrivalEdge ) {
// MaterializeRouting ( edge->getOpposite(vertex), edge);
// // cleaning for next routing
// edge->setSplitter(NULL);
// }
// end_for;
// }
// }
//}
// cleaning for next routing
//vertex->setLocalRingHook(NULL);
vertex->setContact(NULL);
depthMaterialize--;
}
void Graph::CleanRoutingState()
// ****************************
{
// Vide la pile
clearPriorityQueue();
//// Pour chacun des vertex, on efface le pointeur sur la ronde locale et on reinitialise le connexID, la distance et le predecessor
//// le vtuple est aussi mis a NULL, c'est pourquoi il faut que la pile ait été vidée avant ( sinon assert )
//// (XXX mieux vaudrait le faire uniquement pour les vertex touchés par le routage XXX)
//for ( unsigned i = 0 ; i < _all_vertexes.size() ; i++ ) {
// Vertex* vertex = _all_vertexes[i];
// assert (vertex);
// vertex->setLocalRingHook(NULL);
// vertex->setConnexID(-1);
// vertex->setDistance((float)(HUGE_VAL));
// vertex->setPredecessor(NULL);
// assert ( vertex->getVTuple() == NULL );
//}
//// Pour chacune des edges, on efface le pointeur sur le splitter (potentiel) et on reinitialise le connexID
//for ( unsigned i = 0 ; i < _all_edges.size() ; i++ ) {
// Edge* edge = _all_edges[i];
// assert ( edge );
// edge->setSplitter(NULL);
// edge->setConnexID(-1);
//}
// On vide le set des _vertexes_to_route
_vertexes_to_route.clear();
_working_net = NULL;
_searchingArea.makeEmpty();
}
void Graph::checkGraphConsistency()
// ********************************
{
bool checkFailed = false;
unsigned nbEdges= 0;
for_each_edge ( edge, VectorCollection<Edge*>(_all_edges) ) {
nbEdges++;
if ( edge->getNetStamp() > _netStamp ) {
cerr << " - " << edge << " netStamp mismatch" << endl;
checkFailed = true;
}
if ( edge->getNetStamp() == _netStamp ) {
int edgeID = edge->getConnexID();
if ( edgeID != -1 ) {
if ( edge->getFrom()->getConnexID() == -1 ) {
cerr << " - from : " << edge->getFrom() << " of " << edge << " : connexID mismatch" << endl;
checkFailed = true;
}
if ( edge->getTo()->getConnexID() == -1 ) {
cerr << " - to : " << edge->getTo() << " of " << edge << " : connexID mismatch" << endl;
checkFailed = true;
}
if ( (edge->getFrom()->getConnexID() != edgeID) && (edge->getTo()->getConnexID() != edgeID) ) {
cerr << " - " << edge << " : connexID mismatch" << endl;
checkFailed = true;
}
}
}
end_for
}
if ( checkFailed ) {
cerr << " ************************************" << endl
<< " * GRAPH CHECK CONSISTENCY FAILED *" << endl
<< " ************************************" << endl;
}
}
void Graph::checkEmptyPriorityQueue()
// **********************************
{
bool checkFailed = false;
// check empty priority queue
if ( !_vtuplePriorityQueue.empty() ) {
checkFailed = true;
cerr << " Priority Queue is not empty !!!!" << endl
<< " stil in queue :" << endl;
VTuplePQIter pqit = _vtuplePriorityQueue.begin();
while ( pqit != _vtuplePriorityQueue.end() ) {
cerr << " " << (*pqit)->getVertex() << " : " << (*pqit)->getDistance() << endl;
pqit++;
}
}
//check null vtuple foreach vertex
unsigned nbVertexes= 0;
for_each_vertex ( vertex, VectorCollection<Vertex*>(_all_vertexes) ) {
nbVertexes++;
if ( vertex->getNetStamp() > _netStamp ) {
cerr << " - " << vertex << " netStamp mismatch" << endl;
checkFailed = true;
}
if ( vertex->getVTuple() ) {
cerr << " - " << vertex << " still have a vtuple : " << vertex->getVTuple() << endl;
checkFailed = true;
}
end_for
}
if ( checkFailed ) {
cerr << " *********************************************" << endl
<< " * GRAPH CHECK EMPTY PRIORITY QUEUE FAILED *" << endl
<< " *********************************************" << endl;
}
}
// DensityWindow* Graph::createEstimateOccupancyWindow()
// // **************************************************
// {
// if ( _estimateOccupancyWindow ) return _estimateOccupancyWindow;
// unsigned int max = _ySize > _xSize ? _ySize : _xSize;
// unsigned int scale = (unsigned) ceil(500.0/(double)max);
// _estimateOccupancyWindow = new DensityWindow ( _xSize, _ySize, 3, "fire", scale );
// _estimateOccupancyWindow->setName ( 0, "Global Estimate Occupancy" );
// _estimateOccupancyWindow->setName ( 1, "Horizontal Estimate Occupancy" );
// _estimateOccupancyWindow->setName ( 2, "Vertical Estimate Occupancy" );
// return _estimateOccupancyWindow;
// }
// void Graph::UpdateEstimateOccupancyWindow()
// // ****************************************
// {
// if ( !_estimateOccupancyWindow )
// createEstimateOccupancyWindow();
// _estimateOccupancyWindow->setSlice(0);
// Vertex* currentVertex = _lowerLeftVertex;
// int i = 0;
// int j = 0;
// while ( currentVertex ) {
// Vertex* firstLineVertex = currentVertex;
// i = 0;
// while ( currentVertex ) {
// float xEstimateOccupancy = 0.0;
// Edge* hEdgeOut = currentVertex->getHEdgeOut();
// if ( hEdgeOut )
// xEstimateOccupancy += hEdgeOut->getEstimateOccupancy();
// float yEstimateOccupancy = 0.0;
// if ( Edge* vEdgeOut = currentVertex->getVEdgeOut() )
// yEstimateOccupancy += vEdgeOut->getEstimateOccupancy();
// int colorValue = _maxEstimateOccupancy != 0 ? (int)(255 * (xEstimateOccupancy + yEstimateOccupancy) / _maxEstimateOccupancy) : 0;
// int colorXValue = _maxXEstimateOccupancy != 0 ? (int)(255 * xEstimateOccupancy / _maxXEstimateOccupancy) : 0;
// int colorYValue = _maxYEstimateOccupancy != 0 ? (int)(255 * yEstimateOccupancy / _maxYEstimateOccupancy) : 0;
// _estimateOccupancyWindow->DrawRectangle(i, j, i, j, colorValue , 0);
// _estimateOccupancyWindow->DrawRectangle(i, j, i, j, colorXValue, 1);
// _estimateOccupancyWindow->DrawRectangle(i, j, i, j, colorYValue, 2);
// i++;
// if ( hEdgeOut )
// currentVertex = hEdgeOut->getOpposite ( currentVertex );
// else
// break;
// }
// j++;
// Edge* vEdgeOut = firstLineVertex->getVEdgeOut();
// if ( vEdgeOut )
// currentVertex = vEdgeOut->getOpposite ( firstLineVertex );
// else
// break;
// }
// _estimateOccupancyWindow->getWindow()->show();
// return;
// }
//void Graph::printStats()
//// *********************
//{
// Vertex* currentVertex = _lowerLeftVertex;
// int i = 0;
// int j = 0;
// int nbEdgesTotal = 0;
// int nbEdgesOver = 0;
//
// unsigned overflow = 0;
// unsigned maxOver = 0;
// //float maxOver = 0;
// //float averageOver = 0;
// while ( currentVertex ) {
// Vertex* firstLineVertex = currentVertex;
// i = 0;
// while ( currentVertex ) {
// Edge* hEdgeOut = currentVertex->getHEdgeOut();
// if ( hEdgeOut ) {
// nbEdgesTotal++;
// int ov = 2*(hEdgeOut->getRealOccupancy() - hEdgeOut->getCapacity()); // 2 = minimum sapcing + minimum width
// if ( ov > 0 ) {
// nbEdgesOver++;
// overflow += ov;
// maxOver = ov > maxOver ? ov : maxOver;
// for_each_segment ( segment, hEdgeOut->getSegments() ) {
// Net* net = segment->getNet();
// map<Net*, unsigned>::iterator nuit = _netNbOverEdges.find ( net );
// if ( nuit != _netNbOverEdges.end() )
// (*nuit).second = (*nuit).second + 1;
// else
// _netNbOverEdges[net] = 1;
// end_for;
// }
// }
// //float tempOver = (float)hEdgeOut->getRealOccupancy() / (float)hEdgeOut->getCapacity();
// //if ( tempOver > 0.8 ) {
// // nbEdgesOver++;
// // averageOver += tempOver;
// // if ( tempOver > maxOver ) maxOver = tempOver;
// //}
// }
// if ( Edge* vEdgeOut = currentVertex->getVEdgeOut() ) {
// nbEdgesTotal++;
// int ov = 2*(vEdgeOut->getRealOccupancy() - vEdgeOut->getCapacity());
// if ( ov > 0 ) {
// nbEdgesOver++;
// overflow += ov;
// maxOver = ov > maxOver ? ov : maxOver;
// for_each_segment ( segment, vEdgeOut->getSegments() ) {
// Net* net = segment->getNet();
// map<Net*, unsigned>::iterator nuit = _netNbOverEdges.find ( net );
// if ( nuit != _netNbOverEdges.end() )
// (*nuit).second = (*nuit).second + 1;
// else
// _netNbOverEdges[net] = 1;
// end_for;
// }
// }
// //float tempOver = (float)vEdgeOut->getRealOccupancy() / (float)vEdgeOut->getCapacity();
// //if ( tempOver > 0.8 ) {
// // nbEdgesOver++;
// // averageOver += tempOver;
// // if ( tempOver > maxOver ) maxOver = tempOver;
// //}
// }
//
// i++;
// if ( hEdgeOut )
// currentVertex = hEdgeOut->getOpposite ( currentVertex );
// else
// break;
// }
// j++;
// Edge* vEdgeOut = firstLineVertex->getVEdgeOut();
// if ( vEdgeOut )
// currentVertex = vEdgeOut->getOpposite ( firstLineVertex );
// else
// break;
// }
// //averageOver = nbEdgesOver == 0 ? 0 : averageOver / (float)nbEdgesOver;
// //
//
// cerr << " - Total number of edges : " << nbEdgesTotal << endl
// << " - Number of overcapacity edges : " << nbEdgesOver << endl
// << " - Total calls to Dijkstra : " << countDijkstra << endl
// << " - Total calls to Monotonic : " << countMonotonic << endl
// << " - Total calls to Materialize : " << countMaterialize << endl
// << " - Taille du Graphe de routage : " << _xSize << " x " << _ySize << endl
// << endl
// << " - # of overflow : " << overflow << endl
// << " - max of overflow : " << maxOver << endl
// << " - # of net with overflow : " << _netNbOverEdges.size() << endl;
// return;
//}
// DensityWindow* Graph::createOccupancyWindow()
// // ******************************************
// {
// if ( _occupancyWindow ) return _occupancyWindow;
// unsigned int max = _ySize > _xSize ? _ySize : _xSize;
// unsigned int scale = (unsigned) ceil(500.0/(double)max);
// _occupancyWindow = new DensityWindow ( _xSize, _ySize, 3, "fire", scale );
// _occupancyWindow->setName ( 0, "Global Occupancy" );
// _occupancyWindow->setName ( 1, "Horizontal Occupancy" );
// _occupancyWindow->setName ( 2, "Vertical Occupancy" );
// return _occupancyWindow;
// }
// void Graph::UpdateOccupancyWindow()
// // ********************************
// {
// if ( !_occupancyWindow )
// createOccupancyWindow();
// _occupancyWindow->setSlice(0);
// Vertex* currentVertex = _lowerLeftVertex;
// int i = 0;
// int j = 0;
// while ( currentVertex ) {
// Vertex* firstLineVertex = currentVertex;
// i = 0;
// while ( currentVertex ) {
// unsigned xOccupancy = 0;
// Edge* hEdgeOut = currentVertex->getHEdgeOut();
// if ( hEdgeOut )
// xOccupancy += hEdgeOut->getRealOccupancy();
// unsigned yOccupancy = 0;
// if ( Edge* vEdgeOut = currentVertex->getVEdgeOut() )
// yOccupancy += vEdgeOut->getRealOccupancy();
// assert(_maxOccupancy);
// assert(_maxXOccupancy);
// assert(_maxYOccupancy);
// _occupancyWindow->DrawRectangle(i, j, i, j, (255 * (xOccupancy + yOccupancy) / _maxOccupancy), 0);
// _occupancyWindow->DrawRectangle(i, j, i, j, (255 * xOccupancy / _maxXOccupancy), 1);
// _occupancyWindow->DrawRectangle(i, j, i, j, (255 * yOccupancy / _maxYOccupancy), 2);
// i++;
// if ( hEdgeOut )
// currentVertex = hEdgeOut->getOpposite ( currentVertex );
// else
// break;
// }
// j++;
// Edge* vEdgeOut = firstLineVertex->getVEdgeOut();
// if ( vEdgeOut )
// currentVertex = vEdgeOut->getOpposite ( firstLineVertex );
// else
// break;
// }
// _occupancyWindow->getWindow()->show();
// return;
// }
Record* Graph::_getRecord() const
// ************************
{
Record* record = new Record ( getString ( this ) );
record->add ( getSlot ( "LowerLeftVertex", _lowerLeftVertex ) );
// record->add ( getSlot ( "SlicingTree" , _slicingTree ) );
record->add ( getSlot ( "WorkingNet" , _working_net ) );
record->add ( getSlot ( "SearchingArea" , _searchingArea ) );
record->add ( getSlot ( "xSize" , _xSize ) );
record->add ( getSlot ( "ySize" , _ySize ) );
record->add ( getSlot ( "maxEstimateOccupancy", _maxEstimateOccupancy ) );
record->add ( getSlot ( "maxXEstimateOccupancy", _maxXEstimateOccupancy ) );
record->add ( getSlot ( "maxYEstimateOccupancy", _maxYEstimateOccupancy ) );
return record;
}
string Graph::_getString() const
// *****************************
{
return "<" + _TName ( "RoutingGraph" )
//+ ":" + getString ( _slicingTree )
+ "," + getString ( _xSize )
+ "," + getString ( _ySize )
+ ">";
}
} // namespace Knik