diff --git a/.gitignore b/.gitignore index 9a5dba53..b00fe4f6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ *.pyc *.log *.bak + +TAGS + man/ rtf/ html/ diff --git a/crlcore/etc/alliance.conf b/crlcore/etc/alliance.conf index 030a49ec..2516aaab 100644 --- a/crlcore/etc/alliance.conf +++ b/crlcore/etc/alliance.conf @@ -37,13 +37,13 @@ allianceConfig = \ routingGaugesTable = {} routingGaugesTable['sxlib'] = \ - ( ( 'METAL1', ( RoutingLayerGauge.Vertical , RoutingLayerGauge.PinOnly, 0, 0.0, 0, 5, 2, 3 ) ) - , ( 'METAL2', ( RoutingLayerGauge.Horizontal, RoutingLayerGauge.Default, 1, 7.0, 0, 5, 2, 3 ) ) - , ( 'METAL3', ( RoutingLayerGauge.Vertical , RoutingLayerGauge.Default, 2, 0.0, 0, 5, 2, 3 ) ) - , ( 'METAL4', ( RoutingLayerGauge.Horizontal, RoutingLayerGauge.Default, 3, 0.0, 0, 5, 2, 3 ) ) - , ( 'METAL5', ( RoutingLayerGauge.Vertical , RoutingLayerGauge.Default, 4, 0.0, 0, 5, 2, 3 ) ) - #, ( 'METAL6', ( RoutingLayerGauge.Horizontal, RoutingLayerGauge.Default, 5, 0.0, 0, 5, 2, 3 ) ) - #, ( 'METAL7', ( RoutingLayerGauge.Vertical , RoutingLayerGauge.Default, 6, 0.0, 0, 5, 2, 3 ) ) + ( ( 'METAL1', ( RoutingLayerGauge.Vertical , RoutingLayerGauge.PinOnly, 0, 0.0, 0, 5, 2, 2 ) ) + , ( 'METAL2', ( RoutingLayerGauge.Horizontal, RoutingLayerGauge.Default, 1, 7.0, 0, 5, 2, 2 ) ) + , ( 'METAL3', ( RoutingLayerGauge.Vertical , RoutingLayerGauge.Default, 2, 0.0, 0, 5, 2, 2 ) ) + , ( 'METAL4', ( RoutingLayerGauge.Horizontal, RoutingLayerGauge.Default, 3, 0.0, 0, 5, 2, 2 ) ) + , ( 'METAL5', ( RoutingLayerGauge.Vertical , RoutingLayerGauge.Default, 4, 0.0, 0, 5, 2, 2 ) ) + #, ( 'METAL6', ( RoutingLayerGauge.Horizontal, RoutingLayerGauge.Default, 5, 0.0, 0, 5, 2, 2 ) ) + #, ( 'METAL7', ( RoutingLayerGauge.Vertical , RoutingLayerGauge.Default, 6, 0.0, 0, 5, 2, 2 ) ) ) diff --git a/crlcore/etc/display.conf b/crlcore/etc/display.conf index 0e87e496..989f2266 100644 --- a/crlcore/etc/display.conf +++ b/crlcore/etc/display.conf @@ -40,7 +40,7 @@ stylesTable = \ # Group: Routing Layer. , (Group , 'Routing Layer') , (Drawing, 'metal1' , { 'color':'Blue' , 'pattern':'poids2.8' , 'threshold':0.80 }) - , (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.40 }) + , (Drawing, 'metal2' , { 'color':'Aqua' , 'pattern':'light_antihash0.8' , 'threshold':0.02 }) , (Drawing, 'metal3' , { 'color':'LightPink', 'pattern':'light_antihash1.8' , 'threshold':0.02 }) , (Drawing, 'metal4' , { 'color':'Green' , 'pattern':'light_antihash2.8' , 'threshold':0.02 }) , (Drawing, 'metal5' , { 'color':'Yellow' , 'pattern':'1144114411441144' , 'threshold':0.02 }) @@ -137,7 +137,7 @@ stylesTable = \ , (Group , 'Routing Layers') #, (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'light_antislash0.8', 'border':1, 'threshold':0.80 }) , (Drawing, 'metal1', { 'color':'Blue' , 'pattern':'slash.8' , 'border':1, 'threshold':0.80 }) - , (Drawing, 'metal2', { 'color':'Aqua' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.40 }) + , (Drawing, 'metal2', { 'color':'Aqua' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal3', { 'color':'LightPink', 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal4', { 'color':'Green' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) , (Drawing, 'metal5', { 'color':'Yellow' , 'pattern':'poids4.8' , 'border':1, 'threshold':0.02 }) diff --git a/crlcore/etc/kite.conf b/crlcore/etc/kite.conf index f5196466..1709b9b4 100644 --- a/crlcore/etc/kite.conf +++ b/crlcore/etc/kite.conf @@ -6,7 +6,8 @@ parametersTable = \ , ("katabatic.saturateRatio" ,TypePercentage,80 ) , ("katabatic.saturateRp" ,TypeInt ,8 ) # Kite parameters. - , ("kite.edgeCapacity" ,TypePercentage,85 , { 'min':0, 'max':110 } ) + , ("kite.hEdgeCapacity" ,TypePercentage,85 , { 'min':0, 'max':110 } ) + , ("kite.vEdgeCapacity" ,TypePercentage,85 , { 'min':0, 'max':110 } ) , ("kite.eventsLimit" ,TypeInt ,4000002) , ("kite.ripupCost" ,TypeInt ,3 , { 'min':0 } ) , ("kite.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } ) diff --git a/crlcore/src/ccore/GraphicToolEngine.cpp b/crlcore/src/ccore/GraphicToolEngine.cpp index 0e2e312f..8d59cbff 100644 --- a/crlcore/src/ccore/GraphicToolEngine.cpp +++ b/crlcore/src/ccore/GraphicToolEngine.cpp @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | Alliance / Hurricane Interface | // | | @@ -17,23 +11,17 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./GraphicToolEngine.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include - #include "hurricane/Warning.h" #include "crlcore/GraphicToolEngine.h" namespace CRL { - using namespace std; - using Hurricane::Warning; diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp index 7636a931..83ecefac 100644 --- a/crlcore/src/ccore/RoutingGauge.cpp +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2008, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | Alliance / Hurricane Interface | // | | @@ -17,24 +11,19 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./RoutingGauge.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include -#include -#include - -#include "hurricane/Commons.h" -#include "hurricane/Layer.h" -#include "hurricane/Technology.h" -#include "hurricane/DataBase.h" - -#include "crlcore/XmlParser.h" -#include "crlcore/RoutingLayerGauge.h" -#include "crlcore/RoutingGauge.h" +#include +#include +#include +#include "hurricane/Commons.h" +#include "hurricane/ViaLayer.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "crlcore/XmlParser.h" +#include "crlcore/RoutingLayerGauge.h" +#include "crlcore/RoutingGauge.h" namespace { @@ -53,6 +42,7 @@ namespace CRL { using Hurricane::DataBase; + using Hurricane::ViaLayer; // ------------------------------------------------------------------- @@ -60,10 +50,10 @@ namespace CRL { RoutingGauge::RoutingGauge ( const char* name ) - : _name(name) + : _name (name) , _layerGauges() - , _viaLayers() - , _technology(DataBase::getDB()->getTechnology()) + , _viaLayers () + , _technology (DataBase::getDB()->getTechnology()) { } @@ -131,6 +121,15 @@ namespace CRL { } + unsigned int RoutingGauge::getLayerType ( const Layer* layer ) const + { + RoutingLayerGauge* layerGauge = getLayerGauge(layer); + if ( !layerGauge ) return 0; + + return layerGauge->getType(); + } + + unsigned int RoutingGauge::getLayerDirection ( const Layer* layer ) const { RoutingLayerGauge* layerGauge = getLayerGauge(layer); @@ -140,6 +139,21 @@ namespace CRL { } + size_t RoutingGauge::getViaDepth ( const Layer* layer ) const + { + const Layer* bottomLayer = layer; + const Layer* viaLayer = dynamic_cast(layer); + + if (viaLayer) bottomLayer = viaLayer->getBottom(); + + for ( size_t i=0 ; i < _layerGauges.size() ; i++ ) { + if ( _layerGauges[i]->getLayer()->getMask() == bottomLayer->getMask() ) + return i; + } + return UINT_MAX; + } + + size_t RoutingGauge::getLayerDepth ( const Layer* layer ) const { for ( size_t i=0 ; i < _layerGauges.size() ; i++ ) { @@ -171,10 +185,6 @@ namespace CRL { } - unsigned int RoutingGauge::getLayerDirection ( size_t depth ) const - { return getLayerGauge(depth)->getDirection(); } - - const vector& RoutingGauge::getLayerGauges () const { return _layerGauges; diff --git a/crlcore/src/ccore/ToolEngine.cpp b/crlcore/src/ccore/ToolEngine.cpp index 6b592157..ea7528c4 100644 --- a/crlcore/src/ccore/ToolEngine.cpp +++ b/crlcore/src/ccore/ToolEngine.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -102,10 +101,10 @@ namespace { { ToolEngine* tool; while ( (tool = getSlaveOwners().getSubSet().getFirst()) ) { - tool->setInRelationDestroy ( true ); - tool->destroy (); + tool->setInRelationDestroy( true ); + tool->destroy(); } - Relation::_preDestroy (); + Relation::_preDestroy(); } @@ -221,13 +220,14 @@ namespace CRL { void ToolEngine::_preDestroy () { - ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell); - if ( !_inRelationDestroy ) { - if ( !relation ) - throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." ); - remove ( relation ); + ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation( _cell ); + if (not _inRelationDestroy) { + if (not relation) + throw Error( "Abnormal state: no ToolEnginesRelation on %s", getString(_cell).c_str() ); + remove( relation ); } DBo::_preDestroy(); + _cell->notify( Cell::CellChanged ); } diff --git a/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy b/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy index 423fcaa8..b5fc01d1 100644 --- a/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy +++ b/crlcore/src/ccore/alliance/vst/VstParserGrammar.yy @@ -726,7 +726,7 @@ component_instantiation_statement if ( !__ys->_masterCell ) throw Error ( "CParsVst(), Line %d:\n" " Model cell %s of instance %s has not been defined " - "in the compenent list." + "in the component list." , vhdLineNumber, *$2->c_str(), *$1->c_str() ); __ys->_instance = Instance::create ( __ys->_cell, *$1, __ys->_masterCell ); diff --git a/crlcore/src/ccore/crlcore/GraphicToolEngine.h b/crlcore/src/ccore/crlcore/GraphicToolEngine.h index 5f35caee..b702bb4e 100644 --- a/crlcore/src/ccore/crlcore/GraphicToolEngine.h +++ b/crlcore/src/ccore/crlcore/GraphicToolEngine.h @@ -1,31 +1,32 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | Alliance / Hurricane Interface | // | | // | Author : Jean-Paul Chaput | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./crlcore/GraphicTool.h" | -// x-----------------------------------------------------------------x +// | C++ Header : "./crlcore/GraphicToolEngine.h" | +// +-----------------------------------------------------------------+ -#ifndef __CRL_GRAPHIC_TOOL__ -#define __CRL_GRAPHIC_TOOL__ - +#ifndef CRL_GRAPHIC_TOOL_H +#define CRL_GRAPHIC_TOOL_H #include #include +#include #include class QMenu; +#include "hurricane/Error.h" #include "hurricane/viewer/CellWidget.h" +#include "hurricane/viewer/ExceptionWidget.h" namespace Hurricane { @@ -37,19 +38,20 @@ namespace Hurricane { namespace CRL { - using std::string; using std::map; + using Hurricane::Error; + using Hurricane::Exception; using Hurricane::Name; using Hurricane::Cell; using Hurricane::CellWidget; using Hurricane::CellViewer; + using Hurricane::ExceptionWidget; // ------------------------------------------------------------------- // Class : "CRL::GraphicTool". - class GraphicTool : public QObject { Q_OBJECT; @@ -67,7 +69,6 @@ namespace CRL { }; public: typedef map DrawGoMap; - public: void addDrawGo ( const Name& , CellWidget::InitExtensionGo_t* @@ -78,16 +79,12 @@ namespace CRL { virtual void addToMenu ( CellViewer* ) = 0; virtual const Name& getName () const = 0; virtual size_t release () = 0; - signals: - void cellPreModificated (); - void cellPostModificated (); - protected: map _drawGoMap; - protected: - GraphicTool (); - virtual ~GraphicTool (); + GraphicTool (); + virtual ~GraphicTool (); + protected: }; @@ -109,7 +106,6 @@ namespace CRL { { return _drawGoMap; } -} // End of CRL namespace. +} // CRL namespace. - -#endif // __CRL_GRAPHIC_TOOL__ +#endif // CRL_GRAPHIC_TOOL_H diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index 79e0d886..d0d46f81 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,36 +14,33 @@ // +-----------------------------------------------------------------+ -#ifndef __CRL_ROUTING_GAUGE_H__ -#define __CRL_ROUTING_GAUGE_H__ +#ifndef CRL_ROUTING_GAUGE_H +#define CRL_ROUTING_GAUGE_H class QXmlSteamReader; -#include -#include -#include "hurricane/Name.h" -#include "hurricane/Slot.h" +#include +#include +#include "hurricane/Name.h" +#include "hurricane/Slot.h" namespace Hurricane { class Layer; class Technology; } +#include "crlcore/RoutingLayerGauge.h" namespace CRL { - using std::string; using std::vector; - using Hurricane::Name; using Hurricane::Record; using Hurricane::Layer; using Hurricane::Technology; - class RoutingLayerGauge; - // ------------------------------------------------------------------- // Class : "RoutingGauge". @@ -60,11 +56,18 @@ namespace CRL { inline const Name getName () const; inline Technology* getTechnology () const; inline size_t getDepth () const; - size_t getLayerDepth ( const Layer* ) const; RoutingLayerGauge* getLayerGauge ( const Layer* ) const; + size_t getViaDepth ( const Layer* ) const; + size_t getLayerDepth ( const Layer* ) const; + unsigned int getLayerType ( const Layer* ) const; unsigned int getLayerDirection ( const Layer* ) const; RoutingLayerGauge* getLayerGauge ( size_t depth ) const; - unsigned int getLayerDirection ( size_t depth ) const; + inline unsigned int getLayerDirection ( size_t depth ) const; + inline unsigned int getLayerType ( size_t depth ) const; + inline DbU::Unit getLayerPitch ( size_t depth ) const; + inline DbU::Unit getLayerOffset ( size_t depth ) const; + inline DbU::Unit getLayerWireWidth ( size_t depth ) const; + inline DbU::Unit getViaWidth ( size_t depth ) const; const Layer* getRoutingLayer ( size_t depth ) const; Layer* getContactLayer ( size_t depth ) const; const vector& @@ -96,12 +99,16 @@ namespace CRL { inline const Name RoutingGauge::getName () const { return _name; } inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); } inline Technology* RoutingGauge::getTechnology () const { return _technology; } + inline unsigned int RoutingGauge::getLayerType ( size_t depth ) const { return getLayerGauge(depth)->getType(); } + inline unsigned int RoutingGauge::getLayerDirection ( size_t depth ) const { return getLayerGauge(depth)->getDirection(); } + inline DbU::Unit RoutingGauge::getLayerPitch ( size_t depth ) const { return getLayerGauge(depth)->getPitch(); } + inline DbU::Unit RoutingGauge::getLayerOffset ( size_t depth ) const { return getLayerGauge(depth)->getOffset(); } + inline DbU::Unit RoutingGauge::getLayerWireWidth ( size_t depth ) const { return getLayerGauge(depth)->getWireWidth(); } + inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); } -} // End of CRL namespace. - +} // CRL namespace. INSPECTOR_P_SUPPORT(CRL::RoutingGauge); - #endif diff --git a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h index 66ef61e2..20b214d1 100644 --- a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,18 +14,16 @@ // +-----------------------------------------------------------------+ -#ifndef __CRL_ROUTING_LAYER_GAUGE_H__ -#define __CRL_ROUTING_LAYER_GAUGE_H__ +#ifndef CRL_ROUTING_LAYER_GAUGE_H +#define CRL_ROUTING_LAYER_GAUGE_H -#include - -#include "hurricane/Commons.h" -#include "hurricane/DbU.h" -#include "hurricane/Collection.h" -#include "hurricane/Slot.h" - -#include "crlcore/Utilities.h" +#include +#include "hurricane/Commons.h" +#include "hurricane/DbU.h" +#include "hurricane/Collection.h" +#include "hurricane/Slot.h" +#include "crlcore/Utilities.h" namespace Hurricane { class Layer; diff --git a/crlcore/src/ccore/crlcore/ToolEngine.h b/crlcore/src/ccore/crlcore/ToolEngine.h index 7f1e5152..104362a9 100644 --- a/crlcore/src/ccore/crlcore/ToolEngine.h +++ b/crlcore/src/ccore/crlcore/ToolEngine.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -16,16 +15,14 @@ -#ifndef __CRL_TOOL_ENGINE__ -#define __CRL_TOOL_ENGINE__ +#ifndef CRL_TOOL_ENGINE_H +#define CRL_TOOL_ENGINE_H - -#include -#include - -#include "hurricane/Commons.h" -#include "hurricane/DBo.h" -#include "hurricane/Slot.h" +#include +#include +#include "hurricane/Commons.h" +#include "hurricane/DBo.h" +#include "hurricane/Slot.h" namespace Hurricane { class Name; @@ -48,15 +45,13 @@ namespace CRL { // ------------------------------------------------------------------- // Class : "CRL::ToolEngine". - class ToolEngine : public DBo { public: - // Static Methods. static ToolEngines get ( const Cell* cell ); static ToolEngine* get ( const Cell* cell, const Name& name ); static void destroyAll (); static bool inDestroyAll (); - // Methods. + public: virtual const Name& getName () const = 0; inline Cell* getCell () const; bool placementModificationFlagHasChanged (); @@ -65,23 +60,19 @@ namespace CRL { virtual string _getTypeName () const; virtual string _getString () const; virtual Record* _getRecord () const; - private: static bool _inDestroyAll; protected: - // Internal: Attributes Cell* _cell; private: unsigned int _placementModificationFlag; unsigned int _routingModificationFlag; bool _inRelationDestroy; - - // Internal: Constructors & Destructors. protected: ToolEngine ( Cell* cell ); virtual void _postCreate (); virtual void _preDestroy (); - // Internal: Methods. + protected: void grabPlacementModificationFlag (); void getPlacementModificationFlag (); void grabRoutingModificationFlag (); @@ -97,7 +88,6 @@ namespace CRL { inline void ToolEngine::setInRelationDestroy ( bool state ) { _inRelationDestroy = state; } -} // End of CRL namespace. +} // CRL namespace. - -#endif // __CRL_TOOL_ENGINE__ +#endif // CRL_TOOL_ENGINE_H diff --git a/cumulus/src/placeandroute.py b/cumulus/src/placeandroute.py index 7fd9583f..ab840fce 100644 --- a/cumulus/src/placeandroute.py +++ b/cumulus/src/placeandroute.py @@ -2,6 +2,7 @@ import os import re +import Cfg from Hurricane import * from helpers import ErrorMessage import CRL @@ -920,6 +921,14 @@ def pyPowerRing ( cell, core, n ) : global pad_north, pad_south, pad_east, pad_west global RING_INTERVAL, RING_WIDTH + + db = getDataBase() + + topRoutingLayerName = Cfg.getParamString('katabatic.topRoutingLayer', 'METAL4').asString() + topRoutingLayer = db.getTechnology().getLayer( topRoutingLayerName ) + allowedDepth = CRL.AllianceFramework.get().getRoutingGauge().getLayerDepth( topRoutingLayer ) + + print 'topRoutingLayer: <%s> depth:%d' % (topRoutingLayer.getName(), allowedDepth) UpdateSession.open() @@ -951,7 +960,6 @@ def pyPowerRing ( cell, core, n ) : pad_height = getPadHeight ( cell ) # Recuperer les layers ( Vias , Alus ) - db = getDataBase() metal4 = db.getTechnology().getLayer ( "METAL4" ) metal3 = db.getTechnology().getLayer ( "METAL3" ) metal2 = db.getTechnology().getLayer ( "METAL2" ) @@ -959,6 +967,15 @@ def pyPowerRing ( cell, core, n ) : via1 = db.getTechnology().getLayer ( "VIA12" ) via2 = db.getTechnology().getLayer ( "VIA23" ) via3 = db.getTechnology().getLayer ( "VIA34" ) + + if (allowedDepth < 3): + hCoronaLayer = metal2 + vCoronaLayer = metal3 + cCoronaLayer = via2 + else: + hCoronaLayer = metal4 + vCoronaLayer = metal3 + cCoronaLayer = via3 # Recuperer les nets ( qui connectent les connectors du plot : vdde , vsse , vddi , vssi , ck ) instance = cell.getInstance( pad_north[0].getName() ) @@ -1100,25 +1117,25 @@ def pyPowerRing ( cell, core, n ) : for i in range ( 0, 2*n+1, 2 ) : - contact1 = Contact ( vss, via3, init_Xmin - decalage*i, init_Ymin - decalage*i, contact_side, contact_side ) - contact2 = Contact ( vss, via3, init_Xmin - decalage*i, init_Ymax + decalage*i, contact_side, contact_side ) - contact3 = Contact ( vss, via3, init_Xmax + decalage*i, init_Ymax + decalage*i, contact_side, contact_side ) - contact4 = Contact ( vss, via3, init_Xmax + decalage*i, init_Ymin - decalage*i, contact_side, contact_side ) + contact1 = Contact ( vss, cCoronaLayer, init_Xmin - decalage*i, init_Ymin - decalage*i, contact_side, contact_side ) + contact2 = Contact ( vss, cCoronaLayer, init_Xmin - decalage*i, init_Ymax + decalage*i, contact_side, contact_side ) + contact3 = Contact ( vss, cCoronaLayer, init_Xmax + decalage*i, init_Ymax + decalage*i, contact_side, contact_side ) + contact4 = Contact ( vss, cCoronaLayer, init_Xmax + decalage*i, init_Ymin - decalage*i, contact_side, contact_side ) - vertical_west_vss.append ( Vertical ( contact1, contact2, metal3, init_Xmin - decalage*i, DbU_lambda(RING_WIDTH) ) ) - vertical_east_vss.append ( Vertical ( contact3, contact4, metal3, init_Xmax + decalage*i, DbU_lambda(RING_WIDTH) ) ) - horizontal_south_vss.append ( Horizontal ( contact1, contact4, metal4, init_Ymin - decalage*i, DbU_lambda(RING_WIDTH) ) ) - horizontal_north_vss.append ( Horizontal ( contact2, contact3, metal4, init_Ymax + decalage*i, DbU_lambda(RING_WIDTH) ) ) + vertical_west_vss.append ( Vertical ( contact1, contact2, vCoronaLayer, init_Xmin - decalage*i, DbU_lambda(RING_WIDTH) ) ) + vertical_east_vss.append ( Vertical ( contact3, contact4, vCoronaLayer, init_Xmax + decalage*i, DbU_lambda(RING_WIDTH) ) ) + horizontal_south_vss.append ( Horizontal ( contact1, contact4, hCoronaLayer, init_Ymin - decalage*i, DbU_lambda(RING_WIDTH) ) ) + horizontal_north_vss.append ( Horizontal ( contact2, contact3, hCoronaLayer, init_Ymax + decalage*i, DbU_lambda(RING_WIDTH) ) ) if i != 2*n : - contact1 = Contact ( vdd, via3, init_Xmin - decalage* ( i + 1 ), init_Ymin - decalage*( i + 1 ) , contact_side, contact_side ) - contact2 = Contact ( vdd, via3, init_Xmin - decalage* ( i + 1 ), init_Ymax + decalage*( i + 1 ) , contact_side, contact_side ) - contact3 = Contact ( vdd, via3, init_Xmax + decalage* ( i + 1 ), init_Ymax + decalage*( i + 1 ) , contact_side, contact_side ) - contact4 = Contact ( vdd, via3, init_Xmax + decalage* ( i + 1 ), init_Ymin - decalage*( i + 1 ) , contact_side, contact_side ) - vertical_west_vdd.append ( Vertical ( contact1, contact2, metal3, init_Xmin - decalage* ( i + 1 ), DbU_lambda(RING_WIDTH) ) ) - vertical_east_vdd.append ( Vertical ( contact3, contact4, metal3, init_Xmax + decalage* ( i + 1 ), DbU_lambda(RING_WIDTH) ) ) - horizontal_south_vdd.append ( Horizontal ( contact1, contact4, metal4, init_Ymin - decalage* ( i + 1 ), DbU_lambda(RING_WIDTH) ) ) - horizontal_north_vdd.append ( Horizontal ( contact2, contact3, metal4, init_Ymax + decalage* ( i + 1 ), DbU_lambda(RING_WIDTH) ) ) + contact1 = Contact ( vdd, cCoronaLayer, init_Xmin - decalage* ( i + 1 ), init_Ymin - decalage*( i + 1 ) , contact_side, contact_side ) + contact2 = Contact ( vdd, cCoronaLayer, init_Xmin - decalage* ( i + 1 ), init_Ymax + decalage*( i + 1 ) , contact_side, contact_side ) + contact3 = Contact ( vdd, cCoronaLayer, init_Xmax + decalage* ( i + 1 ), init_Ymax + decalage*( i + 1 ) , contact_side, contact_side ) + contact4 = Contact ( vdd, cCoronaLayer, init_Xmax + decalage* ( i + 1 ), init_Ymin - decalage*( i + 1 ) , contact_side, contact_side ) + vertical_west_vdd.append ( Vertical ( contact1, contact2, vCoronaLayer, init_Xmin - decalage* ( i + 1 ), DbU_lambda(RING_WIDTH) ) ) + vertical_east_vdd.append ( Vertical ( contact3, contact4, vCoronaLayer, init_Xmax + decalage* ( i + 1 ), DbU_lambda(RING_WIDTH) ) ) + horizontal_south_vdd.append ( Horizontal ( contact1, contact4, hCoronaLayer, init_Ymin - decalage* ( i + 1 ), DbU_lambda(RING_WIDTH) ) ) + horizontal_north_vdd.append ( Horizontal ( contact2, contact3, hCoronaLayer, init_Ymax + decalage* ( i + 1 ), DbU_lambda(RING_WIDTH) ) ) # MACRO pour les directions d'access des pins UNDEFINED = 0 @@ -1140,7 +1157,8 @@ def pyPowerRing ( cell, core, n ) : _y = core_transformation.getY ( element.getX(), element.getY() ) # Creer un contact a la place du pin - if re.search ( "METAL4", element_layer_name ) : old_contact = Contact ( vss, metal4, _x, _y , element.getHeight(), element.getHeight() ) + if (allowedDepth > 2) and \ + re.search ( "METAL4", element_layer_name ) : old_contact = Contact ( vss, metal4, _x, _y , element.getHeight(), element.getHeight() ) elif re.search ( "METAL1", element_layer_name ) : old_contact = Contact ( vss, metal1, _x, _y , element.getHeight(), element.getHeight() ) elif re.search ( "METAL3", element_layer_name ) : old_contact = Contact ( vss, metal3, _x, _y , element.getHeight(), element.getHeight() ) else : @@ -1160,7 +1178,7 @@ def pyPowerRing ( cell, core, n ) : contact_x = init_Xmin - ( decalage*2 )*i # x du contact a creer contact_side = element.getHeight() - DbU_lambda(1.0) - if re.search ( "METAL4", element_layer_name ) : + if (allowedDepth > 2) and re.search( "METAL4", element_layer_name ) : contact = Contact ( vss, via3 , contact_x , _y , contact_side , contact_side ) horizontal = Horizontal ( contact, old_contact , metal4 , _y , element.getHeight() ) old_contact = contact @@ -1184,7 +1202,7 @@ def pyPowerRing ( cell, core, n ) : contact_x = init_Xmax + ( decalage*2 )*i # x du contact a creer contact_side = element.getHeight() - DbU_lambda(1.0) - if re.search ( "METAL4", element_layer_name ) : + if (allowedDepth > 2) and re.search( "METAL4", element_layer_name ) : contact = Contact ( vss, via3 , contact_x , _y , contact_side, contact_side ) horizontal = Horizontal ( contact, old_contact , metal4 , _y , element.getHeight() ) old_contact = contact @@ -1249,7 +1267,8 @@ def pyPowerRing ( cell, core, n ) : _y = core_transformation.getY ( element.getX(), element.getY() ) # Creer un contact a la place du pin - if re.search ( "METAL4", element_layer_name ) : old_contact = Contact ( vdd, metal4, _x, _y , element.getHeight(), element.getHeight() ) + if (allowedDepth > 2) and \ + re.search ( "METAL4", element_layer_name ) : old_contact = Contact ( vdd, metal4, _x, _y , element.getHeight(), element.getHeight() ) elif re.search ( "METAL1", element_layer_name ) : old_contact = Contact ( vdd, metal1, _x, _y , element.getHeight(), element.getHeight() ) elif re.search ( "METAL3", element_layer_name ) : old_contact = Contact ( vdd, metal3, _x, _y , element.getHeight(), element.getHeight() ) else : @@ -1269,7 +1288,7 @@ def pyPowerRing ( cell, core, n ) : contact_x = init_Xmin - decalage - ( decalage*2 )*i # x du contact a creer contact_side = element.getHeight() - DbU_lambda(1.0) - if re.search ( "METAL4", element_layer_name ) : + if (allowedDepth > 2) and re.search( "METAL4", element_layer_name ) : contact = Contact ( vdd, via3, contact_x, _y, contact_side, contact_side ) horizontal = Horizontal ( contact, old_contact, metal4, _y, element.getHeight() ) old_contact = contact @@ -1293,7 +1312,7 @@ def pyPowerRing ( cell, core, n ) : contact_x = init_Xmax + ( decalage*2 )*i + decalage # x du contact a creer contact_side = element.getHeight() - DbU_lambda(1.0) - if re.search ( "METAL4", element_layer_name ) : + if (allowedDepth > 2) and re.search( "METAL4", element_layer_name ) : contact = Contact ( vdd, via3 , contact_x , _y , contact_side , contact_side ) horizontal = Horizontal ( contact, old_contact , metal4 , _y , element.getHeight() ) old_contact = contact @@ -1365,7 +1384,8 @@ def pyPowerRing ( cell, core, n ) : X = pad_inst.getTransformation().getX ( element.getX(), element.getY() ) Y = pad_inst.getTransformation().getY ( element.getX(), element.getY() ) - contactPad = Contact ( vss, metal1, X, Y, height, height ) + Contact ( vss, via2, X, Y, height, height ) + contactPad = Contact ( vss, via1, X, Y, height, height ) Horizontal ( contactPad, vertical_east_vss[-1], metal1, Y, DbU_lambda ( RING_WIDTH ) ) Contact ( vss, via1, vertical_east_vss[-1].getX(), Y, height, height ) Contact ( vss, via2, vertical_east_vss[-1].getX(), Y, height, height ) @@ -1379,7 +1399,8 @@ def pyPowerRing ( cell, core, n ) : X = pad_inst.getTransformation().getX ( element.getX(), element.getY() ) Y = pad_inst.getTransformation().getY ( element.getX(), element.getY() ) - contactPad = Contact ( vdd, metal1, X, Y, height, height ) + #Contact ( vdd, via2, X, Y, height, height ) + contactPad = Contact ( vdd, via1, X, Y, height, height ) Horizontal ( contactPad, vertical_east_vdd[-1], metal1, Y, DbU_lambda ( RING_WIDTH ) ) Contact ( vdd, via1, vertical_east_vdd[-1].getX(), Y, height, height ) Contact ( vdd, via2, vertical_east_vdd[-1].getX(), Y, height, height ) @@ -1397,7 +1418,8 @@ def pyPowerRing ( cell, core, n ) : X = pad_inst.getTransformation().getX ( element.getX(), element.getY() ) Y = pad_inst.getTransformation().getY ( element.getX(), element.getY() ) - contactPad = Contact ( vss, metal1, X, Y, height, height ) + #Contact ( vss, via2, X, Y, height, height ) + contactPad = Contact ( vss, via1, X, Y, height, height ) Horizontal ( contactPad, vertical_west_vss[-1], metal1, Y, DbU_lambda ( RING_WIDTH ) ) Contact ( vss, via1, vertical_west_vss[-1].getX(), Y, height, height ) Contact ( vss, via2, vertical_west_vss[-1].getX(), Y, height, height ) @@ -1411,7 +1433,8 @@ def pyPowerRing ( cell, core, n ) : X = pad_inst.getTransformation().getX ( element.getX(), element.getY() ) Y = pad_inst.getTransformation().getY ( element.getX(), element.getY() ) - contactPad = Contact ( vdd, metal1, X, Y, height, height ) + #Contact ( vdd, via2, X, Y, height, height ) + contactPad = Contact ( vdd, via1, X, Y, height, height ) Horizontal ( contactPad, vertical_west_vdd[-1], metal1, Y, DbU_lambda ( RING_WIDTH ) ) Contact ( vdd, via1, vertical_west_vdd[-1].getX(), Y, height, height ) Contact ( vdd, via2, vertical_west_vdd[-1].getX(), Y, height, height ) @@ -1430,13 +1453,14 @@ def pyPowerRing ( cell, core, n ) : Y = pad_inst.getTransformation().getY ( element.getX(), element.getY() ) Contact ( vss, via1, X, Y, height, height ) - Contact ( vss, via2, X, Y, height, height ) + #Contact ( vss, via2, X, Y, height, height ) contactPad = Contact ( vss, metal1, X, Y, height, height ) Vertical ( contactPad, horizontal_north_vss[-1], metal1, X , DbU_lambda ( RING_WIDTH ) ) Contact ( vss, via1, X, horizontal_north_vss[-1].getY(), height, height ) - Contact ( vss, via2, X, horizontal_north_vss[-1].getY(), height, height ) - Contact ( vss, via3, X, horizontal_north_vss[-1].getY(), height, height ) + if allowedDepth > 2: + Contact ( vss, via2, X, horizontal_north_vss[-1].getY(), height, height ) + Contact ( vss, via3, X, horizontal_north_vss[-1].getY(), height, height ) for element in NetExternalComponents.get ( pad_inst.getMasterCell().getNet("vddi") ): layer = element.getLayer() @@ -1448,13 +1472,14 @@ def pyPowerRing ( cell, core, n ) : Y = pad_inst.getTransformation().getY ( element.getX(), element.getY() ) Contact ( vdd, via1, X, Y, height, height ) - Contact ( vdd, via2, X, Y, height, height ) + #Contact ( vdd, via2, X, Y, height, height ) contactPad = Contact ( vdd, metal1, X, Y, height, height ) Vertical ( contactPad, horizontal_north_vdd[-1], metal1, X, DbU_lambda ( RING_WIDTH ) ) Contact ( vdd, via1, X, horizontal_north_vdd[-1].getY(), height, height ) - Contact ( vdd, via2, X, horizontal_north_vdd[-1].getY(), height, height ) - Contact ( vdd, via3, X, horizontal_north_vdd[-1].getY(), height, height ) + if allowedDepth > 2: + Contact ( vdd, via2, X, horizontal_north_vdd[-1].getY(), height, height ) + Contact ( vdd, via3, X, horizontal_north_vdd[-1].getY(), height, height ) for pad_inst in pad_south : if isInternalPowerPad ( pad_inst ) or isExternalPowerPad ( pad_inst ) \ @@ -1465,18 +1490,19 @@ def pyPowerRing ( cell, core, n ) : height = element.getBoundingBox().getHeight() - DbU_lambda(1.0) if re.search ( "METAL3", str ( layer ) ) \ - and ( ( element.getY() - ( height / 2 ) ) < pad_inst.getMasterCell().getAbutmentBox().getYMin() ) : + and ( ( element.getY() - ( height / 2 ) ) < pad_inst.getMasterCell().getAbutmentBox().getYMin() ) : X = pad_inst.getTransformation().getX ( element.getX(), element.getY() ) Y = pad_inst.getTransformation().getY ( element.getX(), element.getY() ) Contact ( vss, via1, X, Y, height, height ) - Contact ( vss, via2, X, Y, height, height ) + #Contact ( vss, via2, X, Y, height, height ) contactPad = Contact ( vss, metal1, X, Y, height, height ) Vertical ( contactPad, horizontal_south_vss[-1], metal1, X , DbU_lambda ( RING_WIDTH ) ) Contact ( vss, via1, X, horizontal_south_vss[-1].getY(), height, height ) - Contact ( vss, via2, X, horizontal_south_vss[-1].getY(), height, height ) - Contact ( vss, via3, X, horizontal_south_vss[-1].getY(), height, height ) + if allowedDepth > 2: + Contact ( vss, via2, X, horizontal_south_vss[-1].getY(), height, height ) + Contact ( vss, via3, X, horizontal_south_vss[-1].getY(), height, height ) for element in NetExternalComponents.get ( pad_inst.getMasterCell().getNet("vddi") ): layer = element.getLayer() @@ -1488,13 +1514,14 @@ def pyPowerRing ( cell, core, n ) : Y = pad_inst.getTransformation().getY ( element.getX(), element.getY() ) Contact ( vdd, via1, X, Y, height, height ) - Contact ( vdd, via2, X, Y, height, height ) + #Contact ( vdd, via2, X, Y, height, height ) contactPad = Contact ( vdd, metal1, X, Y, height, height ) Vertical ( contactPad, horizontal_south_vdd[-1], metal1, X , DbU_lambda ( RING_WIDTH ) ) - Contact ( vdd, via1, X, horizontal_south_vdd[-1].getY(), height, height ) - Contact ( vdd, via2, X, horizontal_south_vdd[-1].getY(), height, height ) - Contact ( vdd, via3, X, horizontal_south_vdd[-1].getY(), height, height ) + Contact ( vdd, via1, X, horizontal_south_vdd[-1].getY(), height, height ) + if allowedDepth > 2: + Contact ( vdd, via2, X, horizontal_south_vdd[-1].getY(), height, height ) + Contact ( vdd, via3, X, horizontal_south_vdd[-1].getY(), height, height ) ##################################### ########################### diff --git a/equinox/src/GraphicEquinoxEngine.cpp b/equinox/src/GraphicEquinoxEngine.cpp index fea427da..7c040007 100644 --- a/equinox/src/GraphicEquinoxEngine.cpp +++ b/equinox/src/GraphicEquinoxEngine.cpp @@ -190,11 +190,11 @@ namespace Equinox { EquinoxEngine* equinox = createEngine ( ); if ( !equinox ) return; - emit cellPreModificated (); + //emit cellPreModificated (); equinox->withAlimExtract(1); - emit cellPostModificated (); + //emit cellPostModificated (); } @@ -203,11 +203,11 @@ namespace Equinox { EquinoxEngine* equinox = createEngine ( ); if ( !equinox ) return; - emit cellPreModificated (); + //emit cellPreModificated (); equinox->withoutAlimExtract(1); - emit cellPostModificated (); + //emit cellPostModificated (); } diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 48969e74..ba181fd7 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -250,8 +250,6 @@ namespace Etesian { if (_flags & NoPlacement) return; _flags |= FlatDesign; - //getCell()->flattenNets( true ); - Dots dots ( cmess2, " ", 80, 1000 ); cmess1 << " o Erasing previous placement of <" << getCell()->getName() << ">" << endl; @@ -299,7 +297,7 @@ namespace Etesian { AllianceFramework* af = AllianceFramework::get(); cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; - getCell()->flattenNets( true ); + getCell()->flattenNets( Cell::BuildRings ); // Coloquinte circuit description data-structures. _circuit = new Coloquinte::circuit(); @@ -400,11 +398,19 @@ namespace Etesian { _circuit->position_overlays[0].y_pos[ipair.second] = position.y(); } - _circuit->bounds = Coloquinte::circuit_box - ( Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMin() / DbU::fromLambda(5.0) - , getCell()->getAbutmentBox().getYMin() / DbU::fromLambda(5.0) } ) - , Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMax() / DbU::fromLambda(5.0) - , getCell()->getAbutmentBox().getYMax() / DbU::fromLambda(5.0) } )); + // Temporarily force the circuit size. + getCell()->setAbutmentBox( Box( DbU::fromLambda(0.0) + , DbU::fromLambda(0.0) + , DbU::fromLambda(5.0)*12000 + , DbU::fromLambda(5.0)*12000 + ) ); + _circuit->bounds = Coloquinte::circuit_box( Coloquinte::circuit_coordinate::Zero() + , Coloquinte::circuit_coordinate({12000, 12000}) ); + // _circuit->bounds = Coloquinte::circuit_box + // ( Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMin() / DbU::fromLambda(5.0) + // , getCell()->getAbutmentBox().getYMin() / DbU::fromLambda(5.0) } ) + // , Coloquinte::circuit_coordinate( { getCell()->getAbutmentBox().getXMax() / DbU::fromLambda(5.0) + // , getCell()->getAbutmentBox().getYMax() / DbU::fromLambda(5.0) } )); _circuit->selfcheck(); diff --git a/etesian/src/GraphicEtesianEngine.cpp b/etesian/src/GraphicEtesianEngine.cpp index 1b9a7f24..3b562809 100644 --- a/etesian/src/GraphicEtesianEngine.cpp +++ b/etesian/src/GraphicEtesianEngine.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ namespace Etesian { using Hurricane::Graphics; using Hurricane::ColorScale; using Hurricane::ControllerWidget; + using Hurricane::ExceptionWidget; using CRL::Catalog; using CRL::AllianceFramework; @@ -73,39 +75,45 @@ namespace Etesian { } - EtesianEngine* GraphicEtesianEngine::getForFramework () + EtesianEngine* GraphicEtesianEngine::getForFramework ( unsigned int flags ) { // Currently, only one framework is avalaible: Alliance. EtesianEngine* etesian = EtesianEngine::get( getCell() ); if (etesian) return etesian; - etesian = createEngine(); - - if (not etesian) - throw Error( "Failed to create Etesian engine on %s.", getString(getCell()).c_str() ); + if (flags & CreateEngine) { + etesian = createEngine(); + if (not etesian) + throw Error( "Failed to create Etesian engine on %s.", getString(getCell()).c_str() ); + } else { + throw Error( "EtesianEngine not created yet, out of sequence action." ); + } return etesian; } + void GraphicEtesianEngine::_resetPlacement () + { + _viewer->clearToolInterrupt(); + + EtesianEngine* etesian = getForFramework( CreateEngine ); + etesian->resetPlacement(); + } + + + void GraphicEtesianEngine::_place () + { + EtesianEngine* etesian = getForFramework( CreateEngine ); + etesian->place(); + } + + void GraphicEtesianEngine::place () { - EtesianEngine* etesian = EtesianEngine::get( getCell() ); - if (not etesian) { - etesian = createEngine(); - //throw Error( "EtesianEngine not created yet, run the global router first." ); - } - //if (cmess1.enabled()) etesian->printConfiguration(); - - emit cellPreModificated(); - _viewer->clearToolInterrupt(); - etesian->resetPlacement(); - emit cellPostModificated(); - - emit cellPostModificated(); - etesian->place(); - emit cellPostModificated(); + ExceptionWidget::catchAllWrapper( std::bind(&GraphicEtesianEngine::_resetPlacement,this) ); + ExceptionWidget::catchAllWrapper( std::bind(&GraphicEtesianEngine::_place ,this) ); } @@ -160,9 +168,6 @@ namespace Etesian { connect( placeAction , SIGNAL(triggered()), this, SLOT(place ()) ); } - - connect( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) ); - connect( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) ); } diff --git a/etesian/src/etesian/GraphicEtesianEngine.h b/etesian/src/etesian/GraphicEtesianEngine.h index 3ae15de3..7094ae05 100644 --- a/etesian/src/etesian/GraphicEtesianEngine.h +++ b/etesian/src/etesian/GraphicEtesianEngine.h @@ -50,24 +50,29 @@ namespace Etesian { Q_OBJECT; public: - EtesianEngine* createEngine (); - EtesianEngine* getForFramework (); - static GraphicEtesianEngine* grab (); - virtual const Name& getName () const; - Cell* getCell (); - virtual size_t release (); - virtual void addToMenu ( CellViewer* ); - void postEvent (); - public slots: - void place (); + enum Flags { NoFlags=0x0000, CreateEngine=0x0001 }; + + public: + EtesianEngine* createEngine (); + EtesianEngine* getForFramework ( unsigned int flags ); + static GraphicEtesianEngine* grab (); + virtual const Name& getName () const; + Cell* getCell (); + virtual size_t release (); + virtual void addToMenu ( CellViewer* ); + void postEvent (); + public slots: + void place (); protected: static size_t _references; static GraphicEtesianEngine* _singleton; CellViewer* _viewer; protected: - GraphicEtesianEngine (); - virtual ~GraphicEtesianEngine (); + GraphicEtesianEngine (); + virtual ~GraphicEtesianEngine (); + void _resetPlacement (); + void _place (); }; diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt index a9081486..a5720cbf 100644 --- a/hurricane/src/hurricane/CMakeLists.txt +++ b/hurricane/src/hurricane/CMakeLists.txt @@ -5,6 +5,7 @@ set ( includes hurricane/Mask.h hurricane/DebugSession.h hurricane/Backtrace.h + hurricane/Observer.h hurricane/BasicLayer.h hurricane/BasicLayers.h hurricane/RegularLayer.h hurricane/RegularLayers.h hurricane/ViaLayer.h hurricane/ViaLayers.h @@ -100,6 +101,7 @@ Interruption.cpp Tabulation.cpp DebugSession.cpp + Observer.cpp DbU.cpp Point.cpp Box.cpp diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 12ad3d18..65d62b3c 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -103,7 +103,8 @@ Cell::Cell(Library* library, const Name& name) _isPad(false), _nextOfLibraryCellMap(NULL), _nextOfSymbolCellSet(NULL), - _slaveEntityMap() + _slaveEntityMap(), + _observers() { if (!_library) throw Error("Can't create " + _TName("Cell") + " : null library"); @@ -191,61 +192,70 @@ void Cell::flattenNets(unsigned int flags) // *************************************** { UpdateSession::open(); - bool buildRings = flags & BuildRings; forEach ( Occurrence, ioccurrence, getHyperNetRootNetOccurrences() ) { Net* net = static_cast((*ioccurrence).getEntity()); HyperNet hyperNet ( *ioccurrence ); if ( not (*ioccurrence).getPath().isEmpty() ) { - DeepNet* deepNet = DeepNet::create ( hyperNet ); - if (deepNet) deepNet->_createRoutingPads ( flags ); + DeepNet* deepNet = DeepNet::create( hyperNet ); + if (deepNet) deepNet->_createRoutingPads( flags ); } else { - RoutingPad* previousRP = NULL; - RoutingPad* currentRP = NULL; + RoutingPad* previousRp = NULL; + RoutingPad* currentRp = NULL; + bool buildRing = false; + + if (net->isGlobal()) { + if ( (flags & Cell::BuildClockRings ) and net->isClock () ) buildRing = true; + else if ( (flags & Cell::BuildSupplyRings) and net->isSupply() ) buildRing = true; + } else { + buildRing = flags & Cell::BuildRings; + } forEach ( Component*, icomponent, net->getComponents() ) { Plug* primaryPlug = dynamic_cast( *icomponent ); - if ( primaryPlug ) { + if (primaryPlug) { if ( !primaryPlug->getBodyHook()->getSlaveHooks().isEmpty() ) { cerr << "[ERROR] " << primaryPlug << "\n" << " has attached components, not managed yet." << endl; } else { - primaryPlug->getBodyHook()->detach (); + primaryPlug->getBodyHook()->detach(); } } } forEach ( Occurrence, iplugOccurrence, hyperNet.getLeafPlugOccurrences() ) { - currentRP = RoutingPad::create ( net, *iplugOccurrence, RoutingPad::BiggestArea ); - currentRP->materialize (); - if ( flags & WarnOnUnplacedInstances ) - currentRP->isPlacedOccurrence ( RoutingPad::ShowWarning ); - if ( flags & BuildRings ) { - if ( previousRP ) { - currentRP->getBodyHook()->attach ( previousRP->getBodyHook() ); + currentRp = RoutingPad::create( net, *iplugOccurrence, RoutingPad::BiggestArea ); + currentRp->materialize(); + + if (flags & WarnOnUnplacedInstances) + currentRp->isPlacedOccurrence( RoutingPad::ShowWarning ); + + if (buildRing) { + if (previousRp) { + currentRp->getBodyHook()->attach( previousRp->getBodyHook() ); } Plug* plug = static_cast( (*iplugOccurrence).getEntity() ); if ( (*iplugOccurrence).getPath().isEmpty() ) { - plug->getBodyHook()->attach ( currentRP->getBodyHook() ); - plug->getBodyHook()->detach (); + plug->getBodyHook()->attach( currentRp->getBodyHook() ); + plug->getBodyHook()->detach(); } - previousRP = currentRP; + previousRp = currentRp; } } forEach ( Component*, icomponent, net->getComponents() ) { Pin* pin = dynamic_cast( *icomponent ); - if ( pin ) { - currentRP = RoutingPad::create ( pin ); - if ( buildRings ) { - if ( previousRP ) { - currentRP->getBodyHook()->attach ( previousRP->getBodyHook() ); + if (pin) { + currentRp = RoutingPad::create( pin ); + if (buildRing) { + if (previousRp) { + currentRp->getBodyHook()->attach( previousRp->getBodyHook() ); } - pin->getBodyHook()->attach ( currentRP->getBodyHook() ); - pin->getBodyHook()->detach (); + pin->getBodyHook()->attach( currentRp->getBodyHook() ); + pin->getBodyHook()->detach(); } - previousRP = currentRP; + previousRp = currentRp; } } } @@ -397,6 +407,24 @@ void Cell::_getSlaveEntities(Entity* entity, SlaveEntityMap::iterator& begin, Sl end = _slaveEntityMap.upper_bound(entity); } +void Cell::addObserver(BaseObserver* observer) +// ******************************************* +{ + _observers.addObserver(observer); +} + +void Cell::removeObserver(BaseObserver* observer) +// ********************************************** +{ + _observers.removeObserver(observer); +} + +void Cell::notify(unsigned flags) +// ****************************** +{ + _observers.notify(flags); +} + // **************************************************************************************************** // Cell::InstanceMap implementation // **************************************************************************************************** diff --git a/hurricane/src/hurricane/DebugSession.cpp b/hurricane/src/hurricane/DebugSession.cpp index 5c42e460..06775a5f 100644 --- a/hurricane/src/hurricane/DebugSession.cpp +++ b/hurricane/src/hurricane/DebugSession.cpp @@ -1,7 +1,6 @@ - // -*- C++ -*- // -// Copyright (c) BULL S.A. 2000-2009, All Rights Reserved +// Copyright (c) BULL S.A. 2000-2014, All Rights Reserved // // This file is part of Hurricane. // @@ -19,12 +18,7 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -32,10 +26,7 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./DebugSession.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include diff --git a/hurricane/src/hurricane/DeepNet.cpp b/hurricane/src/hurricane/DeepNet.cpp index 293793ec..376173be 100644 --- a/hurricane/src/hurricane/DeepNet.cpp +++ b/hurricane/src/hurricane/DeepNet.cpp @@ -77,23 +77,37 @@ namespace Hurricane { size_t DeepNet::_createRoutingPads ( unsigned int flags ) { - size_t nbRoutingPads = 0; - HyperNet hyperNet ( _netOccurrence ); + size_t nbRoutingPads = 0; + HyperNet hyperNet ( _netOccurrence ); + RoutingPad* previousRp = NULL; + RoutingPad* currentRp = NULL; + bool buildRing = false; - RoutingPad* previousRP = NULL; - RoutingPad* currentRP = NULL; forEach ( Occurrence, ioccurrence, hyperNet.getLeafPlugOccurrences() ) { nbRoutingPads++; - currentRP = RoutingPad::create( this, *ioccurrence, RoutingPad::BiggestArea ); + currentRp = RoutingPad::create( this, *ioccurrence, RoutingPad::BiggestArea ); if (flags & Cell::WarnOnUnplacedInstances) - currentRP->isPlacedOccurrence ( RoutingPad::ShowWarning ); + currentRp->isPlacedOccurrence ( RoutingPad::ShowWarning ); - if (flags & Cell::BuildRings) { - if (previousRP) { - currentRP->getBodyHook()->attach( previousRP->getBodyHook() ); + if (nbRoutingPads == 1) { + Net* net = currentRp->getNet(); + + if (net->isGlobal()) { + if ( (flags & Cell::BuildClockRings ) and net->isClock () ) buildRing = true; + else if ( (flags & Cell::BuildSupplyRings) and net->isSupply() ) buildRing = true; + } else { + buildRing = flags & Cell::BuildRings; } - previousRP = currentRP; + + //cerr << "_createRoutingPads on " << net->getName() << " buildRing:" << buildRing << endl; + } + + if (buildRing) { + if (previousRp) { + currentRp->getBodyHook()->attach( previousRp->getBodyHook() ); + } + previousRp = currentRp; } } diff --git a/hurricane/src/hurricane/Observer.cpp b/hurricane/src/hurricane/Observer.cpp new file mode 100644 index 00000000..77f057ab --- /dev/null +++ b/hurricane/src/hurricane/Observer.cpp @@ -0,0 +1,65 @@ +// -*- mode: C++; explicit-buffer-name: "Observer.cpp" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2014, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Observer.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/Observer.h" + + +namespace Hurricane { + + using std::cerr; + using std::endl; + + +// ------------------------------------------------------------------- +// Classes : "BaseObserver" & "Observer". + + + void BaseObserver::notify ( unsigned int flags ) + { } + + +// ------------------------------------------------------------------- +// Class : "Observable". + + + void Observable::addObserver ( BaseObserver* observer ) + { + for ( auto iobserver : _observers ) { + if (iobserver == observer) { + cerr << Error( "Observable::addObserver(), trying to add twice the same observer." ) << endl;; + return; + } + } + _observers.push_back( observer ); + } + + + void Observable::removeObserver ( BaseObserver* observer ) + { + vector::iterator iobserver=_observers.begin(); + for ( ; iobserver!=_observers.end() ; ++iobserver ) { + if (*iobserver == observer) { + _observers.erase( iobserver ); + return; + } + } + + cerr << Error( "Observable::removeObserver(), No such observer." ) << endl;; + } + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/UpdateSession.cpp b/hurricane/src/hurricane/UpdateSession.cpp index 2adf4924..2e9ad563 100644 --- a/hurricane/src/hurricane/UpdateSession.cpp +++ b/hurricane/src/hurricane/UpdateSession.cpp @@ -20,6 +20,7 @@ #include "hurricane/UpdateSession.h" #include "hurricane/Go.h" #include "hurricane/Cell.h" +#include "hurricane/Instance.h" #include "hurricane/Error.h" namespace Hurricane { @@ -77,24 +78,30 @@ void UpdateSession::_destroy() Inherit::destroy(); } -void UpdateSession::_preDestroy() -// ***************************** -{ - if (!UPDATOR_STACK || UPDATOR_STACK->empty()) - throw Error("Invalid update session deletion : empty stack"); + void UpdateSession::_preDestroy() + // ****************************** + { + if (not UPDATOR_STACK or UPDATOR_STACK->empty()) + throw Error( "Invalid update session deletion : empty stack" ); if (UPDATOR_STACK->top() != this) - throw Error("Invalid update session deletion : not on top"); + throw Error( "Invalid update session deletion : not on top" ); UPDATOR_STACK->pop(); - for_each_dbo(owner, getOwners()) { - if (dynamic_cast(owner)) ((Go*)owner)->materialize(); - end_for; + forEach( DBo*, iowner, getOwners() ) { + Cell* cell = dynamic_cast(*iowner); + if (cell) { + //cerr << "Notify Cell::CellChanged to: " << cell << endl; + cell->notify( Cell::CellChanged ); + } else { + Go* go = dynamic_cast(*iowner); + if (go) go->materialize(); + } } Inherit::_preDestroy(); -} + } string UpdateSession::_getString() const // ************************************* @@ -111,14 +118,14 @@ Record* UpdateSession::_getRecord() const return record; } -void UpdateSession::onCapturedBy(DBo* owner) -// ***************************************** -{ - if (!dynamic_cast(owner)) - throw Error("Bad update session capture : not a graphic object"); - + void UpdateSession::onCapturedBy(DBo* owner) + // ***************************************** + { + if ( not dynamic_cast(owner) and not dynamic_cast(owner) ) + throw Error( "Bad update session capture : not a graphic object (Go) or a Cell" ); + Inherit::onCapturedBy(owner); -} + } void UpdateSession::onNotOwned() // ***************************** @@ -131,34 +138,44 @@ void UpdateSession::onNotOwned() // Go::invalidate implementation : located here to access UPDATOR_STACK variable // **************************************************************************************************** -void Go::invalidate(bool propagateFlag) -// ************************************ -{ -// trace << "invalidate(" << this << ")" << endl; -// trace_in(); + void Go::invalidate(bool propagateFlag) + // ************************************ + { + // trace << "invalidate(" << this << ")" << endl; + // trace_in(); - if (!UPDATOR_STACK || UPDATOR_STACK->empty()) - throw Error("Can't invalidate go : empty update session stack"); + if (not UPDATOR_STACK or UPDATOR_STACK->empty()) + throw Error( "Can't invalidate go: empty update session stack" ); - Property* property = getProperty(UpdateSession::getPropertyName()); + Property* property = getProperty( UpdateSession::getPropertyName() ); if (property) { - if (!dynamic_cast(property)) - throw Error("Can't invalidate go : bad update session type"); - } - else { - SlaveEntityMap::iterator it; - SlaveEntityMap::iterator end; - getCell()->_getSlaveEntities(this,it,end); - for(; it != end ; it++) { - Go* go = dynamic_cast(it->second); - if (go) go->invalidate(propagateFlag); - } + if (not dynamic_cast(property)) + throw Error( "Can't invalidate go : bad update session type" ); + } else { + SlaveEntityMap::iterator it; + SlaveEntityMap::iterator end; + getCell()->_getSlaveEntities( this, it, end ); + for( ; it!=end ; it++ ) { + Go* go = dynamic_cast( it->second ); + if (go) go->invalidate( propagateFlag ); + } - if (isMaterialized()) { - unmaterialize(); - put(UPDATOR_STACK->top()); + if (isMaterialized()) { + unmaterialize(); + put( UPDATOR_STACK->top() ); + } + + Property* cellUpdateSession = getCell()->getProperty( UpdateSession::getPropertyName() ); + if (not cellUpdateSession) { + // Put the cell in the UpdateSession relation, but *do not* unmaterialize it. + //cerr << "Notify Cell::CellAboutToChange to: " << getCell() << endl; + getCell()->put ( UPDATOR_STACK->top() ); + getCell()->notify( Cell::CellAboutToChange ); + forEach( Instance*, iinstance, getCell()->getSlaveInstances() ) { + iinstance->invalidate( false ); } + } } // trace << "done" << endl; // trace_out(); diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 95b34e7c..53ce1478 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -1,7 +1,7 @@ // **************************************************************************************************** // File: ./hurricane/Cell.h // Authors: R. Escassut -// Copyright (c) BULL S.A. 2000-2009, All Rights Reserved +// Copyright (c) BULL S.A. 2000-2014, All Rights Reserved // // This file is part of Hurricane. // @@ -20,6 +20,7 @@ #ifndef HURRICANE_CELL #define HURRICANE_CELL +#include "hurricane/Observer.h" #include "hurricane/Pathes.h" #include "hurricane/Entity.h" #include "hurricane/Cells.h" @@ -59,12 +60,19 @@ typedef multimap SlaveEntityMap; // **************************************************************************************************** class Cell : public Entity { -// *********************** +// ************************* // Types // ***** - public: enum Flag { BuildRings=0x0001, WarnOnUnplacedInstances=0x0002 }; + public: enum Flag { BuildRings = 0x0001 + , BuildClockRings = 0x0002 + , BuildSupplyRings = 0x0004 + , WarnOnUnplacedInstances = 0x0008 + // Flags set for Observers. + , CellAboutToChange = 0x0001 + , CellChanged = 0x0002 + }; public: typedef Entity Inherit; public: typedef map ExtensionSliceMap; @@ -171,6 +179,7 @@ class Cell : public Entity { private: Cell* _nextOfLibraryCellMap; private: Cell* _nextOfSymbolCellSet; private: SlaveEntityMap _slaveEntityMap; + private: Observable _observers; // Constructors // ************ @@ -306,6 +315,9 @@ class Cell : public Entity { public: void flattenNets(unsigned int flags=BuildRings); public: void materialize(); public: void unmaterialize(); + public: void addObserver(BaseObserver*); + public: void removeObserver(BaseObserver*); + public: void notify(unsigned flags); }; diff --git a/hurricane/src/hurricane/hurricane/Error.h b/hurricane/src/hurricane/hurricane/Error.h index a14e1500..d457b117 100644 --- a/hurricane/src/hurricane/hurricane/Error.h +++ b/hurricane/src/hurricane/hurricane/Error.h @@ -1,7 +1,7 @@ // -*- C++ -*- // -// Copyright (c) BULL S.A. 2000-2009, All Rights Reserved +// Copyright (c) BULL S.A. 2000-2014, All Rights Reserved // // This file is part of Hurricane. // @@ -19,12 +19,7 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -32,14 +27,11 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./hurricane/Error.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __HURRICANE_ERROR__ -#define __HURRICANE_ERROR__ +#ifndef HURRICANE_ERROR_H +#define HURRICANE_ERROR_H #include "hurricane/Exception.h" #include "hurricane/Backtrace.h" @@ -77,7 +69,7 @@ namespace Hurricane { inline string Error::htmlWhere () const { return _backtrace.htmlWhere(); } -} // End of Hurricane namespace. +} // Hurricane namespace. GETSTRING_POINTER_SUPPORT(Hurricane::Error); @@ -86,4 +78,4 @@ IOSTREAM_POINTER_SUPPORT(Hurricane::Error); IOSTREAM_VALUE_SUPPORT(Hurricane::Error); -#endif // __HURRICANE_ERROR__ +#endif // HURRICANE_ERROR_H diff --git a/hurricane/src/hurricane/hurricane/Observer.h b/hurricane/src/hurricane/hurricane/Observer.h new file mode 100644 index 00000000..abc39992 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/Observer.h @@ -0,0 +1,109 @@ +// -*- mode: C++; explicit-buffer-name: "Observer.h" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2014, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/Observer.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_OBSERVER_H +#define HURRICANE_OBSERVER_H + +#include +#include "hurricane/Error.h" + + +namespace Hurricane { + + +// ------------------------------------------------------------------- +// Classes : "BaseObserver" & "Observer". + + class BaseObserver { + public: + virtual void notify ( unsigned int flags ); + template< typename T > + inline T* as (); + }; + + + template< typename T> + inline T* BaseObserver::as () { return dynamic_cast(this); } + + + template< typename T> + class Observer : public BaseObserver { + public: + inline Observer ( const T* owner ); + inline T* getOwner () const; + private: + Observer ( const Observer& ); + private: + static int _ownerOffset; + }; + + + template< typename T> + int Observer::_ownerOffset = -1; + + template< typename T> + inline Observer::Observer ( const T* owner ) + : BaseObserver() + { + if (owner == NULL) + throw Hurricane::Error( "Observer::Observer(), attempt to create with NULL owner." ); + + if (_ownerOffset < 0) + _ownerOffset = (unsigned long)this - (unsigned long)owner; + } + + + template< typename T> + inline T* Observer::getOwner () const { return reinterpret_cast((unsigned long)this - _ownerOffset); } + + +// ------------------------------------------------------------------- +// Class : "Observable". + + class Observable { + public: + inline Observable (); + inline std::vector getObservers (); + void addObserver ( BaseObserver* ); + void removeObserver ( BaseObserver* ); + inline void notify ( unsigned int flags ); + private: + Observable ( const Observable& ); + private: + std::vector _observers; + }; + + + inline Observable::Observable () + : _observers() + { } + + + inline std::vector Observable::getObservers () + { return _observers; } + + + inline void Observable::notify ( unsigned int flags ) + { + for ( auto iobserver : _observers ) { + iobserver->notify( flags ); + } + } + + +} // Hurricane namespace. + +#endif diff --git a/hurricane/src/isobar/hurricane/isobar/PyHurricane.h b/hurricane/src/isobar/hurricane/isobar/PyHurricane.h index 0b062d1b..8e29f846 100644 --- a/hurricane/src/isobar/hurricane/isobar/PyHurricane.h +++ b/hurricane/src/isobar/hurricane/isobar/PyHurricane.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -16,8 +15,8 @@ // +-----------------------------------------------------------------+ -#ifndef __PYHURRICANE__ -#define __PYHURRICANE__ +#ifndef HURRICANE_PYHURRICANE_H +#define HURRICANE_PYHURRICANE_H // Enable Python debugging. // #define DEBUG 1 diff --git a/hurricane/src/viewer/BreakpointWidget.cpp b/hurricane/src/viewer/BreakpointWidget.cpp index 0b16e210..031970fb 100644 --- a/hurricane/src/viewer/BreakpointWidget.cpp +++ b/hurricane/src/viewer/BreakpointWidget.cpp @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -17,22 +11,18 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./BreakpointWidget.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include -#include -#include -#include -#include -#include -#include - -#include "hurricane/Breakpoint.h" -#include "hurricane/viewer/BreakpointWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/Breakpoint.h" +#include "hurricane/viewer/BreakpointWidget.h" namespace Hurricane { @@ -45,9 +35,10 @@ namespace Hurricane { , _isFinished(false) , _eventLoop (NULL) { - setModal ( false ); - setWindowTitle ( "Breakpoint" ); - setToolTip ( "Crush the Mush to continue..." ); + setModal ( false ); + //setWindowModality( Qt::WindowModal ); + setWindowTitle ( "Breakpoint" ); + setToolTip ( "Crush the Mush to continue..." ); _message->setTextFormat ( Qt::RichText ); _message->setText ( "No Message Yet" ); @@ -81,7 +72,13 @@ namespace Hurricane { int BreakpointWidget::execNoModal () { - if ( isVisible() ) return -1; + if (isVisible()) return -1; + + // while (QApplication::hasPendingEvents()) { + // cerr << "Flush events from the main event loop." << endl; + // QApplication::processEvents(); + // } + QApplication::flush(); _isFinished = false; show (); @@ -89,7 +86,7 @@ namespace Hurricane { // Snipet code from Qt's QDialog. _eventLoop = new QEventLoop (); QPointer guard = this; - (void)_eventLoop->exec(QEventLoop::DialogExec); + _eventLoop->exec( QEventLoop::DialogExec ); _eventLoop = NULL; if (guard.isNull()) return QDialog::Rejected; diff --git a/hurricane/src/viewer/CellViewer.cpp b/hurricane/src/viewer/CellViewer.cpp index 3e63d3fd..0f441580 100644 --- a/hurricane/src/viewer/CellViewer.cpp +++ b/hurricane/src/viewer/CellViewer.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | H U R R I C A N E | @@ -15,41 +14,63 @@ // +-----------------------------------------------------------------+ -#include -#include -#include +#include +#include +#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vlsisapd/configuration/Configuration.h" -#include "hurricane/DataBase.h" -#include "hurricane/Cell.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vlsisapd/configuration/Configuration.h" +#include "hurricane/DataBase.h" +#include "hurricane/Cell.h" //#include "MapView.h" -#include "hurricane/viewer/Graphics.h" -#include "hurricane/viewer/CellViewer.h" -#include "hurricane/viewer/CellPrinter.h" -#include "hurricane/viewer/CellImage.h" -#include "hurricane/viewer/MousePositionWidget.h" -#include "hurricane/viewer/ControllerWidget.h" -#include "hurricane/viewer/ScriptWidget.h" -//#include "hurricane/viewer/StratusWidget.h" -#include "hurricane/viewer/GotoWidget.h" -#include "hurricane/viewer/SelectCommand.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/CellViewer.h" +#include "hurricane/viewer/CellPrinter.h" +#include "hurricane/viewer/CellImage.h" +#include "hurricane/viewer/MousePositionWidget.h" +#include "hurricane/viewer/ControllerWidget.h" +#include "hurricane/viewer/ScriptWidget.h" +#include "hurricane/viewer/ExceptionWidget.h" +//#include "hurricane/viewer/StratusWidget.h" +#include "hurricane/viewer/GotoWidget.h" +#include "hurricane/viewer/SelectCommand.h" namespace Hurricane { +// ------------------------------------------------------------------- +// Class : "CellObserver". + + void CellObserver::notify ( unsigned int flags ) + { + CellViewer* viewer = getOwner(); + switch ( flags & (Cell::CellAboutToChange|Cell::CellChanged) ) { + case Cell::CellAboutToChange: + viewer->emitCellAboutToChange(); + break; + case Cell::CellChanged: + viewer->emitCellChanged(); + break; + } + } + + +// ------------------------------------------------------------------- +// Class : "CellViewer". + CellViewer::CellViewer ( QWidget* parent ) : QMainWindow (parent) + , _cellObserver (this) , _applicationName (tr("Viewer")) , _toolInterruptAction (NULL) , _openAction (NULL) @@ -88,6 +109,7 @@ namespace Hurricane { , _cellHistory () , _firstShow (false) , _toolInterrupt (false) + , _flags (0) , _updateState (ExternalEmit) { setObjectName("viewer"); @@ -282,71 +304,73 @@ namespace Hurricane { void CellViewer::createLayout () { - if ( _cellWidget ) return; + if (_cellWidget) return; - _cellWidget = new CellWidget (); - _controller = new ControllerWidget (); - _goto = new GotoWidget (); - _goto->changeDbuMode ( _cellWidget->getDbuMode(), _cellWidget->getUnitPower() ); + _cellWidget = new CellWidget (); + _controller = new ControllerWidget(); + _goto = new GotoWidget (); + _goto->changeDbuMode( _cellWidget->getDbuMode(), _cellWidget->getUnitPower() ); //_mapView = _cellWidget->getMapView (); - _cellWidget->bindCommand ( &_moveCommand ); - _cellWidget->bindCommand ( &_zoomCommand ); - _cellWidget->bindCommand ( &_rulerCommand ); - _cellWidget->bindCommand ( &_selectCommand ); - _cellWidget->bindCommand ( &_hierarchyCommand ); - _controller->setCellWidget ( _cellWidget ); + _cellWidget->bindCommand( &_moveCommand ); + _cellWidget->bindCommand( &_zoomCommand ); + _cellWidget->bindCommand( &_rulerCommand ); + _cellWidget->bindCommand( &_selectCommand ); + _cellWidget->bindCommand( &_hierarchyCommand ); + _controller->setCellWidget( _cellWidget ); - MousePositionWidget* _mousePosition = new MousePositionWidget (); - statusBar()->addPermanentWidget ( _mousePosition ); + MousePositionWidget* _mousePosition = new MousePositionWidget(); + statusBar()->addPermanentWidget( _mousePosition ); - setCorner ( Qt::TopLeftCorner , Qt::LeftDockWidgetArea ); - setCorner ( Qt::BottomLeftCorner , Qt::LeftDockWidgetArea ); - setCorner ( Qt::TopRightCorner , Qt::RightDockWidgetArea ); - setCorner ( Qt::BottomRightCorner, Qt::RightDockWidgetArea ); + setCorner( Qt::TopLeftCorner , Qt::LeftDockWidgetArea ); + setCorner( Qt::BottomLeftCorner , Qt::LeftDockWidgetArea ); + setCorner( Qt::TopRightCorner , Qt::RightDockWidgetArea ); + setCorner( Qt::BottomRightCorner, Qt::RightDockWidgetArea ); - // QDockWidget* mapViewDock = new QDockWidget ( tr("Map") ); - // mapViewDock->setFeatures ( QDockWidget::DockWidgetVerticalTitleBar - // | QDockWidget::DockWidgetMovable - // | QDockWidget::DockWidgetFloatable - // ); - // mapViewDock->setObjectName ( "viewer.menuBar.dock.mapView" ); - // mapViewDock->setWidget ( _mapView ); - // mapViewDock->setAllowedAreas ( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); - // addDockWidget ( Qt::RightDockWidgetArea, mapViewDock ); + //QDockWidget* mapViewDock = new QDockWidget ( tr("Map") ); + //mapViewDock->setFeatures ( QDockWidget::DockWidgetVerticalTitleBar + // | QDockWidget::DockWidgetMovable + // | QDockWidget::DockWidgetFloatable + // ); + //mapViewDock->setObjectName ( "viewer.menuBar.dock.mapView" ); + //mapViewDock->setWidget ( _mapView ); + //mapViewDock->setAllowedAreas ( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); + //addDockWidget( Qt::RightDockWidgetArea, mapViewDock ); - setCentralWidget ( _cellWidget ); + setCentralWidget( _cellWidget ); - connect ( this , SIGNAL(redrawCellWidget()) , _cellWidget, SLOT(refresh()) ); - connect ( _refreshAction , SIGNAL(triggered()) , _cellWidget, SLOT(refresh()) ); - connect ( _fitToContentsAction , SIGNAL(triggered()) , _cellWidget, SLOT(fitToContents()) ); - connect ( _showSelectionAction , SIGNAL(toggled(bool)) , this , SLOT(setShowSelection(bool)) ); - connect ( _rubberChangeAction , SIGNAL(triggered()) , _cellWidget, SLOT(rubberChange()) ); - connect ( _clearRulersAction , SIGNAL(triggered()) , _cellWidget, SLOT(clearRulers()) ); - connect ( _controllerAction , SIGNAL(triggered()) , _controller, SLOT(toggleShow()) ); - connect ( _scriptAction , SIGNAL(triggered()) , this , SLOT(runScript()) ); - //connect ( _stratusAction , SIGNAL(triggered()) , this , SLOT(runStratusScript()) ); - connect ( _gotoAction , SIGNAL(triggered()) , this , SLOT(doGoto()) ); + connect( this , SIGNAL(cellPreModificated()) , _cellWidget, SLOT(cellPreModificate()) ); + connect( this , SIGNAL(cellPostModificated()), _cellWidget, SLOT(cellPostModificate()) ); + connect( this , SIGNAL(redrawCellWidget()) , _cellWidget, SLOT(refresh()) ); + connect( _refreshAction , SIGNAL(triggered()) , _cellWidget, SLOT(refresh()) ); + connect( _fitToContentsAction , SIGNAL(triggered()) , _cellWidget, SLOT(fitToContents()) ); + connect( _showSelectionAction , SIGNAL(toggled(bool)) , this , SLOT(setShowSelection(bool)) ); + connect( _rubberChangeAction , SIGNAL(triggered()) , _cellWidget, SLOT(rubberChange()) ); + connect( _clearRulersAction , SIGNAL(triggered()) , _cellWidget, SLOT(clearRulers()) ); + connect( _controllerAction , SIGNAL(triggered()) , _controller, SLOT(toggleShow()) ); + connect( _scriptAction , SIGNAL(triggered()) , this , SLOT(runScript()) ); + //connect( _stratusAction , SIGNAL(triggered()) , this , SLOT(runStratusScript()) ); + connect( _gotoAction , SIGNAL(triggered()) , this , SLOT(doGoto()) ); - connect ( _cellWidget , SIGNAL(dbuModeChanged(unsigned int,DbU::UnitPower)) - , _goto , SLOT (changeDbuMode (unsigned int,DbU::UnitPower)) ); + connect( _cellWidget , SIGNAL(dbuModeChanged(unsigned int,DbU::UnitPower)) + , _goto , SLOT (changeDbuMode (unsigned int,DbU::UnitPower)) ); - connect ( _cellWidget , SIGNAL(mousePositionChanged(const Point&)) - , _mousePosition , SLOT (setPosition(const Point&)) ); + connect( _cellWidget , SIGNAL(mousePositionChanged(const Point&)) + , _mousePosition , SLOT (setPosition(const Point&)) ); - connect ( _cellWidget , SIGNAL(selectionModeChanged()) - , this , SLOT (changeSelectionMode ()) ); - // connect ( &_selectCommand , SIGNAL(selectionToggled (Occurrence)) - // , _cellWidget , SLOT (toggleSelection (Occurrence)) ); - connect ( &_selectCommand , SIGNAL(selectionToggled (Occurrence)) - , _cellWidget , SLOT (select (Occurrence)) ); + connect( _cellWidget , SIGNAL(selectionModeChanged()) + , this , SLOT (changeSelectionMode ()) ); + //connect( &_selectCommand , SIGNAL(selectionToggled (Occurrence)) + // , _cellWidget , SLOT (toggleSelection (Occurrence)) ); + connect( &_selectCommand , SIGNAL(selectionToggled (Occurrence)) + , _cellWidget , SLOT (select (Occurrence)) ); - connect ( _cellWidget , SIGNAL(stateChanged(shared_ptr&)) - , this , SLOT (setState (shared_ptr&)) ); - connect ( this , SIGNAL(stateChanged(shared_ptr&)) - , _cellWidget , SLOT (setState (shared_ptr&)) ); + connect( _cellWidget , SIGNAL(stateChanged(shared_ptr&)) + , this , SLOT (setState (shared_ptr&)) ); + connect( this , SIGNAL(stateChanged(shared_ptr&)) + , _cellWidget , SLOT (setState (shared_ptr&)) ); - _cellWidget->refresh (); + _cellWidget->refresh(); } @@ -409,17 +433,22 @@ namespace Hurricane { void CellViewer::setCell ( Cell* cell ) { + if (cell == getCell()) return; + if (getCell()) getCell()->removeObserver( getCellObserver() ); + Name cellName = (cell) ? cell->getName() : "empty"; list< shared_ptr >::iterator istate - = find_if ( _cellHistory.begin(), _cellHistory.end(), CellWidget::FindStateName(cellName) ); + = find_if( _cellHistory.begin(), _cellHistory.end(), CellWidget::FindStateName(cellName) ); - if ( istate != _cellHistory.end() ) { + if (istate != _cellHistory.end()) { + (*istate)->getCell()->addObserver( getCellObserver() ); emit stateChanged ( *istate ); return; } - _cellWidget->setCell ( cell ); + cell->addObserver( getCellObserver() ); + _cellWidget->setCell( cell ); } @@ -590,8 +619,12 @@ namespace Hurricane { } + void CellViewer::_runScript () + { ScriptWidget::runScript( this, getCell() ); } + + void CellViewer::runScript () - { ScriptWidget::runScript ( this, getCell() ); } + { ExceptionWidget::catchAllWrapper( std::bind( &CellViewer::_runScript, this ) ); } //void CellViewer::runStratusScript () diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp index f36df6e4..14ddf250 100644 --- a/hurricane/src/viewer/CellWidget.cpp +++ b/hurricane/src/viewer/CellWidget.cpp @@ -1,4 +1,3 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. diff --git a/hurricane/src/viewer/ControllerWidget.cpp b/hurricane/src/viewer/ControllerWidget.cpp index 8a562a6a..e978c1c4 100644 --- a/hurricane/src/viewer/ControllerWidget.cpp +++ b/hurricane/src/viewer/ControllerWidget.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -231,8 +230,8 @@ namespace Hurricane { } else { getCellWidget()->setShowSelection ( false ); getCellWidget()->setCumulativeSelection ( _cwCumulativeSelection ); - _netlistBrowser->disconnect ( getCellWidget(), SLOT(select (const Net*)) ); - _netlistBrowser->disconnect ( getCellWidget(), SLOT(unselect(const Net*)) ); + _netlistBrowser->disconnect ( getCellWidget(), SLOT(select (Occurrence)) ); + _netlistBrowser->disconnect ( getCellWidget(), SLOT(unselect(Occurrence)) ); } } diff --git a/hurricane/src/viewer/ExceptionWidget.cpp b/hurricane/src/viewer/ExceptionWidget.cpp index c231e26e..e60e2b60 100644 --- a/hurricane/src/viewer/ExceptionWidget.cpp +++ b/hurricane/src/viewer/ExceptionWidget.cpp @@ -1,4 +1,3 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. @@ -15,24 +14,24 @@ // +-----------------------------------------------------------------+ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "hurricane/Error.h" -#include "hurricane/Exception.h" -#include "hurricane/viewer/Graphics.h" -#include "hurricane/viewer/ExceptionWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/Error.h" +#include "hurricane/Exception.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/ExceptionWidget.h" namespace Hurricane { @@ -65,6 +64,30 @@ namespace Hurricane { } + void ExceptionWidget::catchAllWrapper ( std::function< void() > method ) + { + try { + method(); + } + catch ( Error& e ) { + ExceptionWidget::run( e ); + } + catch ( Exception& e ) { + ExceptionWidget::run( e ); + } + catch ( std::exception& e ) { + ExceptionWidget::run( e ); + } + catch ( ... ) { + static const char* message = + "  Unmanaged exception, neither a Hurricane::Error
" + "nor a std::exception."; + + ExceptionWidget::run( message ); + } + } + + ExceptionWidget::ExceptionWidget ( QWidget* parent ) : QDialog (parent) , _header (new QLabel()) diff --git a/hurricane/src/viewer/Graphics.cpp b/hurricane/src/viewer/Graphics.cpp index ca071f6f..d7f8c126 100644 --- a/hurricane/src/viewer/Graphics.cpp +++ b/hurricane/src/viewer/Graphics.cpp @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -17,24 +11,18 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./Graphics.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include - -#include -#include -#include -#include - -#include "hurricane/Name.h" -#include "hurricane/Exception.h" - -#include "hurricane/viewer/DisplayStyle.h" -#include "hurricane/viewer/Graphics.h" +#include +#include +#include +#include +#include +#include "hurricane/Name.h" +#include "hurricane/Exception.h" +#include "hurricane/viewer/DisplayStyle.h" +#include "hurricane/viewer/Graphics.h" namespace Hurricane { @@ -335,12 +323,12 @@ namespace Hurricane { { static BreakpointWidget* bpw = NULL; - if ( !bpw ) - bpw = new BreakpointWidget (); - bpw->setMessage ( message.c_str() ); - bpw->execNoModal (); + if (not bpw) + bpw = new BreakpointWidget(); + bpw->setMessage( message.c_str() ); + bpw->execNoModal(); - return ( bpw->result() == QDialog::Accepted ); + return (bpw->result() == QDialog::Accepted); } diff --git a/hurricane/src/viewer/NetlistWidget.cpp b/hurricane/src/viewer/NetlistWidget.cpp index cb3b2a90..df843330 100644 --- a/hurricane/src/viewer/NetlistWidget.cpp +++ b/hurricane/src/viewer/NetlistWidget.cpp @@ -1,40 +1,30 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./NetlistWidget.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include -#include -#include -#include -#include -#include -#include -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "hurricane/Commons.h" #include "hurricane/Net.h" - #include "hurricane/viewer/Graphics.h" #include "hurricane/viewer/NetlistModel.h" #include "hurricane/viewer/NetlistWidget.h" @@ -42,7 +32,6 @@ namespace { - using namespace Hurricane; diff --git a/hurricane/src/viewer/PaletteWidget.cpp b/hurricane/src/viewer/PaletteWidget.cpp index 44fdb73e..1127794d 100644 --- a/hurricane/src/viewer/PaletteWidget.cpp +++ b/hurricane/src/viewer/PaletteWidget.cpp @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -17,39 +11,32 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./PaletteWidget.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include - -#include -#include -#include -#include -#include -#include - -#include "hurricane/DataBase.h" -#include "hurricane/Technology.h" -#include "hurricane/BasicLayer.h" -#include "hurricane/BasicLayers.h" -#include "hurricane/ExtensionSlice.h" -#include "hurricane/Cell.h" - -#include "hurricane/viewer/Graphics.h" -#include "hurricane/viewer/PaletteItem.h" -#include "hurricane/viewer/PaletteNamedItem.h" -#include "hurricane/viewer/PaletteLayerItem.h" -#include "hurricane/viewer/PaletteExtensionGoItem.h" -#include "hurricane/viewer/PaletteWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/BasicLayers.h" +#include "hurricane/ExtensionSlice.h" +#include "hurricane/Cell.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/PaletteItem.h" +#include "hurricane/viewer/PaletteNamedItem.h" +#include "hurricane/viewer/PaletteLayerItem.h" +#include "hurricane/viewer/PaletteExtensionGoItem.h" +#include "hurricane/viewer/PaletteWidget.h" namespace { - using namespace std; using namespace Hurricane; @@ -130,7 +117,7 @@ namespace { } -} // End of anonymous namespace. +} // Anonymous namespace. namespace Hurricane { @@ -313,13 +300,15 @@ namespace Hurricane { void PaletteWidget::updateExtensions ( Cell* cell ) { _grid->removeWidget ( _extensionGroup ); - _extensionGroup->deleteLater (); + //_extensionGroup->deleteLater (); + delete _extensionGroup; _extensionGroup = NULL; PaletteItems::iterator iextension = _extensionGoItems.begin(); for ( ; iextension != _extensionGoItems.end() ; ++iextension ) { _grid->removeWidget ( iextension->second ); - iextension->second->deleteLater (); + //iextension->second->deleteLater (); + delete iextension->second; } _extensionGoItems.clear (); @@ -492,4 +481,4 @@ namespace Hurricane { } -} // End of Hurricane namespace. +} // Hurricane namespace. diff --git a/hurricane/src/viewer/ScriptWidget.cpp b/hurricane/src/viewer/ScriptWidget.cpp index b3020563..58648ea4 100644 --- a/hurricane/src/viewer/ScriptWidget.cpp +++ b/hurricane/src/viewer/ScriptWidget.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/hurricane/src/viewer/hurricane/viewer/BreakpointWidget.h b/hurricane/src/viewer/hurricane/viewer/BreakpointWidget.h index 8190d80d..ca46925d 100644 --- a/hurricane/src/viewer/hurricane/viewer/BreakpointWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/BreakpointWidget.h @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -17,18 +11,14 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Header : "./BreakpointWidget.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __HURRICANE_BREAKPOINT_WIDGET__ -#define __HURRICANE_BREAKPOINT_WIDGET__ +#ifndef HURRICANE_BREAKPOINT_WIDGET_H +#define HURRICANE_BREAKPOINT_WIDGET_H - -#include -#include +#include +#include class QLabel; class QSpinBox; @@ -59,7 +49,6 @@ namespace Hurricane { -} // End of Hurricane namespace. +} // Hurricane namespace. - -#endif // __HURRICANE_BREAKPOINT_WIDGET__ +#endif // HURRICANE_BREAKPOINT_WIDGET_H diff --git a/hurricane/src/viewer/hurricane/viewer/CellViewer.h b/hurricane/src/viewer/hurricane/viewer/CellViewer.h index 5b841144..92658f03 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/CellViewer.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | H U R R I C A N E | @@ -15,16 +14,14 @@ // +-----------------------------------------------------------------+ -#ifndef __HURRICANE_CELL_VIEWER__ -#define __HURRICANE_CELL_VIEWER__ - - -#include +#ifndef HURRICANE_CELL_VIEWER_H +#define HURRICANE_CELL_VIEWER_H +#include +#include using namespace std; -#include - +#include class QEvent; class QKeyEvent; class QAction; @@ -32,9 +29,9 @@ class QMenu; class QPrinter; #include "hurricane/Commons.h" +#include "hurricane/Observer.h" #include "hurricane/Name.h" #include "hurricane/Occurrence.h" - #include "hurricane/viewer/MoveCommand.h" #include "hurricane/viewer/ZoomCommand.h" #include "hurricane/viewer/RulerCommand.h" @@ -52,13 +49,35 @@ namespace Hurricane { class MousePositionWidget; class ControllerWidget; class ScriptWidget; + class CellViewer; +// ------------------------------------------------------------------- +// Class : "CellObserver". + + class CellObserver : public Observer { + public: + inline CellObserver ( CellViewer* ); + virtual void notify ( unsigned int flags ); + private: + CellObserver ( const CellObserver& ); + }; + + + inline CellObserver::CellObserver ( CellViewer* owner ) + : Observer(owner) + { } + + +// ------------------------------------------------------------------- +// Class : "CellViewer". + class CellViewer : public QMainWindow { Q_OBJECT; public: - enum { CellHistorySize = 10 }; + enum { CellHistorySize = 10 }; + enum Flag { InCellChange = 0x0001 }; public: CellViewer ( QWidget* parent=NULL ); virtual ~CellViewer (); @@ -66,6 +85,7 @@ namespace Hurricane { QMenu* createDebugMenu (); inline void setEnableRedrawInterrupt ( bool ); inline void setApplicationName ( const QString& ); + inline CellObserver* getCellObserver (); Cell* getCell () const; virtual void setCell ( Cell* ); void renameCell ( const char* ); @@ -78,6 +98,7 @@ namespace Hurricane { void unselect ( Occurrence& ); void unselectAll (); inline void setLayerVisible ( const Name& layer, bool visible ); + void _runScript (); virtual std::string _getString () const; public slots: void doGoto (); @@ -92,10 +113,14 @@ namespace Hurricane { void clearToolInterrupt (); void runScript (); //void runStratusScript (); + inline void emitCellAboutToChange (); + inline void emitCellChanged (); signals: void showSelectionToggled ( bool ); void stateChanged ( shared_ptr& ); void redrawCellWidget (); + void cellPreModificated (); + void cellPostModificated (); protected: void createActions (); void createMenus (); @@ -104,6 +129,7 @@ namespace Hurricane { void refreshHistory (); protected: + CellObserver _cellObserver; QString _applicationName; QAction* _toolInterruptAction; QAction* _openAction; @@ -144,18 +170,22 @@ namespace Hurricane { _cellHistory; bool _firstShow; bool _toolInterrupt; + unsigned int _flags; UpdateState _updateState; }; // Inline Functions. - inline bool CellViewer::isToolInterrupted () const { return _toolInterrupt; } - inline CellWidget* CellViewer::getCellWidget () { return _cellWidget; } - inline const CellWidget* CellViewer::getCellWidget () const { return _cellWidget; } - inline ControllerWidget* CellViewer::getControllerWidget () { return _controller; } - inline void CellViewer::setApplicationName ( const QString& name ) { _applicationName = name; } - inline void CellViewer::setLayerVisible ( const Name& layer, bool visible ) { _cellWidget->setLayerVisible(layer,visible); } + inline bool CellViewer::isToolInterrupted () const { return _toolInterrupt; } + inline CellObserver* CellViewer::getCellObserver () { return &_cellObserver; } + inline CellWidget* CellViewer::getCellWidget () { return _cellWidget; } + inline const CellWidget* CellViewer::getCellWidget () const { return _cellWidget; } + inline ControllerWidget* CellViewer::getControllerWidget () { return _controller; } + inline void CellViewer::setApplicationName ( const QString& name ) { _applicationName = name; } + inline void CellViewer::setLayerVisible ( const Name& layer, bool visible ) { _cellWidget->setLayerVisible(layer,visible); } + inline void CellViewer::emitCellAboutToChange () { _flags |= InCellChange; emit cellPreModificated(); } + inline void CellViewer::emitCellChanged () { _flags &= ~InCellChange; emit cellPostModificated(); } inline void CellViewer::setEnableRedrawInterrupt ( bool state ) { _cellWidget->setEnableRedrawInterrupt(state); } diff --git a/hurricane/src/viewer/hurricane/viewer/CellWidget.h b/hurricane/src/viewer/hurricane/viewer/CellWidget.h index 61cfe67c..d7a7508a 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/CellWidget.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,24 +14,21 @@ // +-----------------------------------------------------------------+ -#ifndef __HURRICANE_CELL_WIDGET_H__ -#define __HURRICANE_CELL_WIDGET_H__ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include +#ifndef HURRICANE_CELL_WIDGET_H +#define HURRICANE_CELL_WIDGET_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include class QCursor; class QShowEvent; class QResizeEvent; @@ -40,22 +36,18 @@ class QMouseEvent; class QKeyEvent; class QAction; - -#include "hurricane/Timer.h" -#include "hurricane/Commons.h" -#include "hurricane/Warning.h" -#include "hurricane/Point.h" -#include "hurricane/Box.h" -#include "hurricane/Transformation.h" -#include "hurricane/Query.h" - -#include "hurricane/viewer/DisplayStyle.h" -#include "hurricane/viewer/CellWidgets.h" -#include "hurricane/viewer/Selector.h" -#include "hurricane/viewer/SelectorCriterion.h" -#include "hurricane/viewer/Ruler.h" - - +#include "hurricane/Timer.h" +#include "hurricane/Commons.h" +#include "hurricane/Warning.h" +#include "hurricane/Point.h" +#include "hurricane/Box.h" +#include "hurricane/Transformation.h" +#include "hurricane/Query.h" +#include "hurricane/viewer/DisplayStyle.h" +#include "hurricane/viewer/CellWidgets.h" +#include "hurricane/viewer/Selector.h" +#include "hurricane/viewer/SelectorCriterion.h" +#include "hurricane/viewer/Ruler.h" namespace Hurricane { @@ -74,7 +66,6 @@ namespace Hurricane { class Segment; class Contact; class Pad; - class Selector; class PaletteWidget; class Command; diff --git a/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h b/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h index aa57f2ad..6bbd67e6 100644 --- a/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -17,16 +11,14 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Header : "./ExceptionWidget.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __HURRICANE_EXCEPTION_WIDGET__ -#define __HURRICANE_EXCEPTION_WIDGET__ +#ifndef HURRICANE_EXCEPTION_WIDGET_H +#define HURRICANE_EXCEPTION_WIDGET_H #include +#include #include class QLabel; class QTextEdit; @@ -45,6 +37,7 @@ namespace Hurricane { static void run ( Exception& ); static void run ( std::exception& ); static void run ( const QString&, const QString& where="" ); + static void catchAllWrapper ( std::function< void() > method ); public: ExceptionWidget ( QWidget* parent=NULL); void setMessage ( const QString& ); @@ -60,6 +53,6 @@ namespace Hurricane { }; -} // End of Hurricane namespace. +} // Hurricane namespace. -#endif // __HURRICANE_EXCEPTION_WIDGET__ +#endif // HURRICANE_EXCEPTION_WIDGET_H diff --git a/hurricane/src/viewer/hurricane/viewer/ScriptWidget.h b/hurricane/src/viewer/hurricane/viewer/ScriptWidget.h index 9e179bf2..1b00afe0 100644 --- a/hurricane/src/viewer/hurricane/viewer/ScriptWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/ScriptWidget.h @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -17,14 +11,11 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Header : "./ScriptWidget.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __HURRICANE_SCRIPT_WIDGET__ -#define __HURRICANE_SCRIPT_WIDGET__ +#ifndef HURRICANE_SCRIPT_WIDGET_H +#define HURRICANE_SCRIPT_WIDGET_H #include @@ -48,8 +39,7 @@ namespace Hurricane { }; -} // End of Hurricane namespace. +} // Hurricane namespace. - -#endif // __HURRICANE_SCRIPT_WIDGET__ +#endif // HURRICANE_SCRIPT_WIDGET_H diff --git a/katabatic/src/AutoContactHTee.cpp b/katabatic/src/AutoContactHTee.cpp index e4b91d62..9dc62ebd 100644 --- a/katabatic/src/AutoContactHTee.cpp +++ b/katabatic/src/AutoContactHTee.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2012-2013, All Rights Reserved +// Copyright (c) UPMC 2012-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -52,13 +52,14 @@ namespace Katabatic { AutoContactHTee* AutoContactHTee::create ( GCell* gcell, Net* net, const Layer* layer ) { - Contact* contact = Contact::create ( net - , layer - , gcell->getCenter().getX() - , gcell->getCenter().getY() - , DbU::lambda(2.0) - , DbU::lambda(2.0) - ); + DbU::Unit viaSide = Session::getViaWidth( layer ); + Contact* contact = Contact::create ( net + , layer + , gcell->getCenter().getX() + , gcell->getCenter().getY() + , viaSide + , viaSide + ); AutoContactHTee* autoContact = new AutoContactHTee ( gcell, contact ); autoContact->_postCreate(); diff --git a/katabatic/src/AutoContactTurn.cpp b/katabatic/src/AutoContactTurn.cpp index 416c648a..cd657c91 100644 --- a/katabatic/src/AutoContactTurn.cpp +++ b/katabatic/src/AutoContactTurn.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2012-2012, All Rights Reserved +// Copyright (c) UPMC 2012-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -55,13 +54,14 @@ namespace Katabatic { { _preCreate( gcell, net, layer ); - Contact* contact = Contact::create ( net - , layer - , gcell->getCenter().getX() - , gcell->getCenter().getY() - , DbU::lambda(2.0) - , DbU::lambda(2.0) - ); + DbU::Unit viaSide = Session::getViaWidth( layer ); + Contact* contact = Contact::create ( net + , layer + , gcell->getCenter().getX() + , gcell->getCenter().getY() + , viaSide + , viaSide + ); AutoContactTurn* autoContact = new AutoContactTurn ( gcell, contact ); autoContact->_postCreate(); diff --git a/katabatic/src/AutoContactVTee.cpp b/katabatic/src/AutoContactVTee.cpp index 7b00704e..33915ce1 100644 --- a/katabatic/src/AutoContactVTee.cpp +++ b/katabatic/src/AutoContactVTee.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2012-2013, All Rights Reserved +// Copyright (c) UPMC 2012-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -53,13 +52,14 @@ namespace Katabatic { AutoContactVTee* AutoContactVTee::create ( GCell* gcell, Net* net, const Layer* layer ) { - Contact* contact = Contact::create( net - , layer - , gcell->getCenter().getX() - , gcell->getCenter().getY() - , DbU::lambda(2.0) - , DbU::lambda(2.0) - ); + DbU::Unit viaSide = Session::getViaWidth( layer ); + Contact* contact = Contact::create( net + , layer + , gcell->getCenter().getX() + , gcell->getCenter().getY() + , viaSide + , viaSide + ); AutoContactVTee* autoContact = new AutoContactVTee( gcell, contact ); autoContact->_postCreate(); diff --git a/katabatic/src/AutoHorizontal.cpp b/katabatic/src/AutoHorizontal.cpp index c022c096..8679a658 100644 --- a/katabatic/src/AutoHorizontal.cpp +++ b/katabatic/src/AutoHorizontal.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -227,12 +226,17 @@ namespace Katabatic { { ltracein(200); + Interval sourceSide = getAutoSource()->getGCell()->getSide( KbVertical ); + Interval targetSide = getAutoTarget()->getGCell()->getSide( KbVertical ); Interval sourceConstraints = Interval(getAutoSource()->getCBYMin(),getAutoSource()->getCBYMax()); Interval targetConstraints = Interval(getAutoTarget()->getCBYMin(),getAutoTarget()->getCBYMax()); // Ugly: should uses topRightShrink from GCell. - sourceConstraints.inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); - targetConstraints.inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + //sourceConstraints.inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + //targetConstraints.inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + // Expand by a tiny amount for the "contains" to work for sure. + sourceConstraints.inflate( 1 ); + targetConstraints.inflate( 1 ); ltrace(200) << "source " << getAutoSource() << endl; ltrace(200) << "source constraints: " << sourceConstraints @@ -242,8 +246,10 @@ namespace Katabatic { << " " << DbU::getValueString(targetConstraints.getSize()) << endl; // Ugly: GCell's track number is hardwired. - if (sourceConstraints.getSize() / DbU::lambda(5.0) < 10) { ltraceout(200); return true; } - if (targetConstraints.getSize() / DbU::lambda(5.0) < 10) { ltraceout(200); return true; } + //if (sourceConstraints.getSize() / DbU::lambda(5.0) < 10) { ltraceout(200); return true; } + //if (targetConstraints.getSize() / DbU::lambda(5.0) < 10) { ltraceout(200); return true; } + if (not sourceConstraints.contains(sourceSide)) { ltraceout(200); return true; } + if (not targetConstraints.contains(targetSide)) { ltraceout(200); return true; } ltraceout(200); return false; @@ -274,14 +280,14 @@ namespace Katabatic { isMetal2Target = (target->getLayer() == metal2); } - if (height >= 4*DbU::lambda(5.0)) { - if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*DbU::lambda(5.0))) + if (height >= 4*getPitch()) { + if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch())) return false; } ltracein(200); ltrace(200) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl; - ltrace(200) << "test:" << (getLength() < DbU::lambda(5.0)*5) << endl; + ltrace(200) << "test:" << (getLength() < 5*getPitch()) << endl; ltrace(200) << "length:" << DbU::getValueString(getLength()) << endl; int lowSlack = (flags & KbHalfSlacken) ? 3 : 10; @@ -294,8 +300,8 @@ namespace Katabatic { Interval perpandConstraints = getAutoTarget()->getUConstraints(KbHorizontal); Interval constraints = source->getUConstraints (KbVertical).inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); Interval nativeConstraints = source->getNativeUConstraints(KbVertical).inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); - int slack = constraints.getSize() / DbU::lambda(5.0); - int nativeSlack = nativeConstraints.getSize() / DbU::lambda(5.0); + int slack = constraints.getSize() / getPitch(); + int nativeSlack = nativeConstraints.getSize() / getPitch(); ltrace(200) << "Source constraint: " << constraints << " slack:" << slack @@ -330,8 +336,8 @@ namespace Katabatic { if (target->isTerminal()) { Interval constraints = target->getUConstraints (KbVertical).inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); Interval nativeConstraints = target->getNativeUConstraints(KbVertical).inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); - int slack = constraints.getSize() / DbU::lambda(5.0); - int nativeSlack = nativeConstraints.getSize() / DbU::lambda(5.0); + int slack = constraints.getSize() / getPitch(); + int nativeSlack = nativeConstraints.getSize() / getPitch(); // Ugly: GCell's track number is hardwired. ltrace(200) << "Target constraint: " << constraints @@ -711,7 +717,7 @@ namespace Katabatic { } size_t depth = Session::getRoutingGauge()->getLayerDepth( _horizontal->getLayer() ); - bool upLayer = (depth+1 < Session::getRoutingGauge()->getDepth()); + bool upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); Layer* contactLayer = Session::getRoutingGauge()->getContactLayer( depth + ((upLayer)?0:-1) ); const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer( depth + ((upLayer)?1:-1) ); diff --git a/katabatic/src/AutoSegment.cpp b/katabatic/src/AutoSegment.cpp index ab7103d9..4a300d6c 100644 --- a/katabatic/src/AutoSegment.cpp +++ b/katabatic/src/AutoSegment.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -311,6 +311,7 @@ namespace Katabatic { AutoSegment::AutoSegment ( Segment* segment ) : _id (segment->getId()) , _flags (SegCreated) + , _depth (Session::getLayerDepth(segment->getLayer())) , _optimalMin (0) , _sourcePosition (0) , _targetPosition (0) @@ -1266,7 +1267,7 @@ namespace Katabatic { if ( isLocal() and (not (flags & KbAllowLocal )) ) return false; size_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2; - if (depth >= Session::getConfiguration()->getAllowedDepth()) return false; + if (depth > Session::getConfiguration()->getAllowedDepth()) return false; vector gcells; getGCells( gcells ); @@ -1363,7 +1364,7 @@ namespace Katabatic { if ( isLayerChange() or isFixed() /*or isTerminal()*/ or isLocal() ) return false; size_t upDepth = Session::getRoutingGauge()->getLayerDepth(getLayer()) + 2; - if ( upDepth >= Session::getConfiguration()->getAllowedDepth() ) return false; + if ( upDepth > Session::getConfiguration()->getAllowedDepth() ) return false; vector gcells; getGCells ( gcells ); @@ -1578,8 +1579,8 @@ namespace Katabatic { if (leftCandidate) { DbU::Unit axis; // Ugly: Hard-wired track spacing. - if (leftDogleg) axis = interval.getVMin() - DbU::lambda(5.0); - else axis = interval.getVMax() + DbU::lambda(5.0); + if (leftDogleg) axis = interval.getVMin() - getPitch(); + else axis = interval.getVMax() + getPitch(); ltrace(200) << "Break @" << DbU::getValueString(axis) << " " << leftCandidate << endl; @@ -1616,7 +1617,9 @@ namespace Katabatic { if (doglegGCell->isUnderIoPad()) { cerr << Bug( "Attempt to make a dogleg in a GCell under a Pad\n" + " %s\n" " %s" + , getString(this).c_str() , getString(doglegGCell).c_str() ) << endl; } @@ -1818,7 +1821,9 @@ namespace Katabatic { ) { static const Layer* horizontalLayer = Session::getRoutingLayer( 1 ); + static DbU::Unit horizontalWidth = Session::getWireWidth ( 1 ); static const Layer* verticalLayer = Session::getRoutingLayer( 2 ); + static DbU::Unit verticalWidth = Session::getWireWidth ( 2 ); AutoSegment* segment; AutoContact* reference = source; @@ -1853,7 +1858,7 @@ namespace Katabatic { , target->base() , horizontalLayer , reference->getY() - , DbU::lambda(2.0) ) ); + , horizontalWidth ) ); } else if (dir & KbVertical) { segment = create( source , target @@ -1861,7 +1866,7 @@ namespace Katabatic { , target->base() , verticalLayer , reference->getX() - , DbU::lambda(2.0) + , verticalWidth ) ); } else throw Error( badSegment, getString(source).c_str(), getString(target).c_str() ); diff --git a/katabatic/src/AutoVertical.cpp b/katabatic/src/AutoVertical.cpp index 4992c70b..791e9f50 100644 --- a/katabatic/src/AutoVertical.cpp +++ b/katabatic/src/AutoVertical.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -19,6 +18,7 @@ #include "hurricane/Bug.h" #include "hurricane/Vertical.h" #include "crlcore/RoutingGauge.h" +#include "katabatic/Configuration.h" #include "katabatic/AutoContactTurn.h" #include "katabatic/AutoVertical.h" #include "katabatic/AutoHorizontal.h" @@ -219,16 +219,23 @@ namespace Katabatic { { ltraceout(200); + Interval sourceSide = getAutoSource()->getGCell()->getSide( KbHorizontal ); + Interval targetSide = getAutoTarget()->getGCell()->getSide( KbHorizontal ); Interval sourceConstraints = Interval(getAutoSource()->getCBXMin(),getAutoSource()->getCBXMax()); Interval targetConstraints = Interval(getAutoTarget()->getCBXMin(),getAutoTarget()->getCBXMax()); // Ugly: should uses topRightShrink from GCell. - sourceConstraints.inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); - targetConstraints.inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + //sourceConstraints.inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + //targetConstraints.inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); + // Expand by a tiny amount for the "contains" to work for sure. + sourceConstraints.inflate( 1 ); + targetConstraints.inflate( 1 ); // Ugly: GCell's track number is hardwired. - if (sourceConstraints.getSize() / DbU::lambda(5.0) < 10) { ltraceout(200); return true; } - if (targetConstraints.getSize() / DbU::lambda(5.0) < 10) { ltraceout(200); return true; } + //if (sourceConstraints.getSize() / DbU::lambda(5.0) < 10) { ltraceout(200); return true; } + //if (targetConstraints.getSize() / DbU::lambda(5.0) < 10) { ltraceout(200); return true; } + if (not sourceConstraints.contains(sourceSide)) { ltraceout(200); return true; } + if (not targetConstraints.contains(targetSide)) { ltraceout(200); return true; } ltraceout(200); return false; @@ -241,11 +248,11 @@ namespace Katabatic { ltracein(200); if ( not isStrongTerminal() - or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < DbU::lambda(5.0)*5)) ) + or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) ) { ltraceout(200); return false; } ltrace(200) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl; - ltrace(200) << "test:" << (getLength() < DbU::lambda(5.0)*5) << endl; + ltrace(200) << "test:" << (getLength() < getPitch()*5) << endl; ltrace(200) << "length:" << DbU::getValueString(getLength()) << endl; bool success = false; @@ -258,8 +265,8 @@ namespace Katabatic { if (source->isTerminal()) { Interval constraints = source->getUConstraints (KbHorizontal).inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); Interval nativeConstraints = source->getNativeUConstraints(KbHorizontal).inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); - int slack = constraints.getSize() / DbU::lambda(5.0); - int nativeSlack = nativeConstraints.getSize() / DbU::lambda(5.0); + int slack = constraints.getSize() / getPitch(); + int nativeSlack = nativeConstraints.getSize() / getPitch(); // Ugly: GCell's track number is hardwired. if ((slack < lowSlack) or (nativeSlack - slack < 3)) { @@ -289,8 +296,8 @@ namespace Katabatic { if (target->isTerminal()) { Interval constraints = target->getUConstraints (KbHorizontal).inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); Interval nativeConstraints = target->getNativeUConstraints(KbHorizontal).inflate( 0, /*Katabatic::GCell::getTopRightShrink()*/ DbU::lambda(1.0) ); - int slack = constraints.getSize() / DbU::lambda(5.0); - int nativeSlack = nativeConstraints.getSize() / DbU::lambda(5.0); + int slack = constraints.getSize() / getPitch(); + int nativeSlack = nativeConstraints.getSize() / getPitch(); // Ugly: GCell's track number is hardwired. if ((slack < lowSlack) or (nativeSlack - slack < 3)) { @@ -628,7 +635,7 @@ namespace Katabatic { } size_t depth = Session::getRoutingGauge()->getLayerDepth ( _vertical->getLayer() ); - bool upLayer = (depth+1 < Session::getRoutingGauge()->getDepth()); + bool upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) ); const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + ((upLayer)?1:-1) ); diff --git a/katabatic/src/ChipTools.cpp b/katabatic/src/ChipTools.cpp index a1fb4158..ac892f31 100644 --- a/katabatic/src/ChipTools.cpp +++ b/katabatic/src/ChipTools.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/katabatic/src/Configuration.cpp b/katabatic/src/Configuration.cpp index 52c1e9f9..4e77d0d4 100644 --- a/katabatic/src/Configuration.cpp +++ b/katabatic/src/Configuration.cpp @@ -1,7 +1,7 @@ // -*- mode: C++; explicit-buffer-name: "Configuration.cpp" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -10,16 +10,16 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Module : "./Configuartion.cpp" | +// | C++ Module : "./Configuration.cpp" | // +-----------------------------------------------------------------+ #include #include #include - #include "vlsisapd/configuration/Configuration.h" #include "hurricane/Warning.h" +#include "hurricane/Error.h" #include "hurricane/Technology.h" #include "hurricane/DataBase.h" #include "hurricane/Cell.h" @@ -42,6 +42,7 @@ namespace Katabatic { using Hurricane::tab; using Hurricane::inltrace; using Hurricane::Warning; + using Hurricane::Error; using Hurricane::Technology; using Hurricane::DataBase; using CRL::AllianceFramework; @@ -62,20 +63,23 @@ namespace Katabatic { ConfigurationConcrete::ConfigurationConcrete ( const RoutingGauge* rg ) - : Configuration() - , _rg (NULL) - , _extensionCap (DbU::lambda(0.5)) - , _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble()) - , _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt()) - , _globalThreshold (DbU::lambda((double)Cfg::getParamInt("katabatic.globalLengthThreshold",29*50)->asInt())) // Ugly: direct uses of SxLib gauge. - , _allowedDepth (0) - , _hEdgeCapacity (0) - , _vEdgeCapacity (0) + : Configuration () + , _rg (NULL) + , _extensionCap (DbU::lambda(0.5)) + , _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble()) + , _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt()) + , _globalThreshold(DbU::lambda((double)Cfg::getParamInt("katabatic.globalLengthThreshold",29*50)->asInt())) // Ugly: direct uses of SxLib gauge. + , _allowedDepth (0) + , _hEdgeCapacity (0) + , _vEdgeCapacity (0) { - if ( rg == NULL ) rg = AllianceFramework::get()->getRoutingGauge(); + if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge(); + _rg = rg->getClone(); - _rg = rg->getClone(); - _allowedDepth = rg->getDepth(); + if (Cfg::hasParameter("katabatic.topRoutingLayer")) { + _setTopRoutingLayer( Cfg::getParamString("katabatic.topRoutingLayer")->asString() ); + } else + _allowedDepth = rg->getDepth()-1; _gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh"); _gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv"); @@ -88,12 +92,12 @@ namespace Katabatic { vector::const_iterator ilayerGauge = rg->getLayerGauges().begin(); for ( ; ilayerGauge != rg->getLayerGauges().end() ; ++ilayerGauge ) { RoutingLayerGauge* layerGauge = (*ilayerGauge); - if ( layerGauge->getType() != Constant::Default ) continue; + if (layerGauge->getType() != Constant::Default) continue; - if ( layerGauge->getDirection() == Constant::Horizontal ) { + if (layerGauge->getDirection() == Constant::Horizontal) { _hEdgeCapacity += layerGauge->getTrackNumber ( 0, DbU::lambda(50.0) ) - 1; - } else if ( layerGauge->getDirection() == Constant::Vertical ) { - _vEdgeCapacity += layerGauge->getTrackNumber ( 0, DbU::lambda(50.0) ) - 1; + } else if (layerGauge->getDirection() == Constant::Vertical) { + _vEdgeCapacity += layerGauge->getTrackNumber( 0, DbU::lambda(50.0) ) - 1; } } } @@ -169,6 +173,61 @@ namespace Katabatic { { return _extensionCap; } + DbU::Unit ConfigurationConcrete::getPitch ( const Layer* layer, unsigned int flags ) const + { return getPitch( getLayerDepth(layer), flags ); } + + + DbU::Unit ConfigurationConcrete::getOffset ( const Layer* layer ) const + { return getOffset( getLayerDepth(layer) ); } + + + DbU::Unit ConfigurationConcrete::getWireWidth ( const Layer* layer ) const + { return getWireWidth( getLayerDepth(layer) ); } + + + unsigned int ConfigurationConcrete::getDirection ( const Layer* layer ) const + { return getDirection( getLayerDepth(layer) ); } + + + DbU::Unit ConfigurationConcrete::getPitch ( size_t depth, unsigned int flags ) const + { + if (flags == NoFlags) return _rg->getLayerPitch(depth); + + if (flags & Configuration::PitchAbove) { + if (depth < getAllowedDepth()) + return _rg->getLayerPitch( depth + 1 ); + else { + if ( (depth > 0) and (_rg->getLayerType(depth-1) != Constant::PinOnly) ) + return _rg->getLayerPitch( depth - 1 ); + } + } + + if (flags & Configuration::PitchBelow) { + if ( (depth > 0) and (_rg->getLayerType(depth-1) != Constant::PinOnly) ) + return _rg->getLayerPitch( depth - 1 ); + else { + if (depth < getAllowedDepth()) + return _rg->getLayerPitch( depth + 1 ); + } + } + + // Should issue at least a warning here. + return _rg->getLayerPitch(depth); + } + + + DbU::Unit ConfigurationConcrete::getOffset ( size_t depth ) const + { return _rg->getLayerOffset(depth); } + + + DbU::Unit ConfigurationConcrete::getWireWidth ( size_t depth ) const + { return _rg->getLayerWireWidth(depth); } + + + unsigned int ConfigurationConcrete::getDirection ( size_t depth ) const + { return _rg->getLayerDirection(depth); } + + float ConfigurationConcrete::getSaturateRatio () const { return _saturateRatio; } @@ -193,6 +252,21 @@ namespace Katabatic { { _allowedDepth = (allowedDepth > getDepth()) ? getDepth() : allowedDepth; } + void ConfigurationConcrete::_setTopRoutingLayer ( Name name ) + { + for ( size_t depth=0 ; depth<_rg->getDepth() ; ++depth ) { + if (_rg->getRoutingLayer(depth)->getName() == name) { + _allowedDepth = _rg->getLayerGauge(depth)->getDepth(); + return; + } + } + cerr << Error( "In Configuration::Concrete::_setTopRoutingLayer():\n" + " The routing gauge <%s> has no layer named <%s>" + , getString(_rg->getName()).c_str() + , getString(name).c_str() ) << endl; + } + + void ConfigurationConcrete::setSaturateRatio ( float ratio ) { _saturateRatio = ratio; } @@ -207,8 +281,14 @@ namespace Katabatic { void ConfigurationConcrete::print ( Cell* cell ) const { + string topLayerName = "UNKOWN"; + const Layer* topLayer = _rg->getRoutingLayer( _allowedDepth ); + if (topLayer) + topLayerName = getString( topLayer->getName() ); + cout << " o Configuration of ToolEngine for Cell <" << cell->getName() << ">" << endl; cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl; + cout << Dots::asString (" - Top routing layer" ,topLayerName) << endl; cout << Dots::asPercentage(" - GCell saturation threshold" ,_saturateRatio) << endl; cout << Dots::asDouble (" - Long global length threshold",DbU::getLambda(_globalThreshold)) << endl; } @@ -239,6 +319,9 @@ namespace Katabatic { record->add ( getSlot ( "_gcontact" , _gcontact ) ); record->add ( getSlot ( "_saturateRatio" , _saturateRatio ) ); record->add ( DbU::getValueSlot ( "_globalThreshold" , &_globalThreshold ) ); + record->add ( getSlot ( "_allowedDepth" , _allowedDepth ) ); + record->add ( getSlot ( "_hEdgeCapacity" , _hEdgeCapacity ) ); + record->add ( getSlot ( "_vEdgeCapacity" , _vEdgeCapacity ) ); return ( record ); } diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index 6c019cda..985be6d0 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -80,14 +80,17 @@ namespace { public: UsedFragments (); ~UsedFragments (); + inline DbU::Unit getPitch () const; inline DbU::Unit getMin () const; inline DbU::Unit getMax () const; Interval getMaxFree () const; inline void setSpan ( DbU::Unit min, DbU::Unit max ); inline void setCapacity ( size_t ); inline void incGlobals ( size_t count=1 ); + inline void setPitch ( DbU::Unit ); void merge ( DbU::Unit axis, const Interval& ); private: + DbU::Unit _pitch; vector _axiss; Interval _span; size_t _capacity; @@ -100,8 +103,8 @@ namespace { , _axis (axis) , _chunks () { - merge ( Interval ( ufragments->getMin()-DbU::lambda(5.0), ufragments->getMin() ) ); - merge ( Interval ( ufragments->getMax(), ufragments->getMax()+DbU::lambda(5.0) ) ); + merge ( Interval ( ufragments->getMin()-ufragments->getPitch(), ufragments->getMin() ) ); + merge ( Interval ( ufragments->getMax(), ufragments->getMax()+ufragments->getPitch() ) ); } inline DbU::Unit UsedFragments::Axis::getAxis () const { return _axis; } @@ -180,7 +183,8 @@ namespace { UsedFragments::UsedFragments () - : _axiss () + : _pitch (0) + , _axiss () , _span (false) , _capacity(0) , _globals (0) @@ -196,8 +200,10 @@ namespace { } + inline DbU::Unit UsedFragments::getPitch () const { return _pitch; } inline DbU::Unit UsedFragments::getMin () const { return _span.getVMin(); } inline DbU::Unit UsedFragments::getMax () const { return _span.getVMax(); } + inline void UsedFragments::setPitch ( DbU::Unit pitch ) { _pitch=pitch; } inline void UsedFragments::setSpan ( DbU::Unit min, DbU::Unit max ) { _span=Interval(min,max); } inline void UsedFragments::setCapacity ( size_t capacity ) { _capacity=capacity; } inline void UsedFragments::incGlobals ( size_t count ) { _globals+=count; } @@ -529,13 +535,13 @@ namespace Katabatic { float GCell::getHCapacity () const { - return (float)( _box.getHeight() / DbU::lambda(5.0) + 1 ); + return (float)( _box.getHeight() / Session::getPitch(1) + 1 ); } float GCell::getVCapacity () const { - return (float)( _box.getWidth () / DbU::lambda(5.0) + 1 ); + return (float)( _box.getWidth () / Session::getPitch(2) + 1 ); } @@ -764,17 +770,18 @@ namespace Katabatic { UsedFragments ufragments [ _depth ]; for ( size_t i=0 ; i<_depth ; i++ ) { + ufragments [i].setPitch ( Session::getPitch(i) ); _feedthroughs[i] = 0.0; uLengths2 [i] = 0; localCounts [i] = 0.0; _globalsCount[i] = 0.0; - switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { - case Constant::Horizontal: + switch ( Session::getDirection(i) ) { + case KbHorizontal: ufragments[i].setSpan ( _box.getXMin(), _box.getXMax() ); ufragments[i].setCapacity ( (size_t)hcapacity ); break; - case Constant::Vertical: + case KbVertical: ufragments[i].setSpan ( _box.getYMin(), _box.getYMax() ); ufragments[i].setCapacity ( (size_t)vcapacity ); break; @@ -789,9 +796,9 @@ namespace Katabatic { for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0; (*it)->getLengths ( uLengths1, processeds ); for ( size_t i=0 ; i<_depth ; i++ ) { - switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { - case Constant::Horizontal: uLengths2[i] += uLengths1[i]+hpenalty; break; - case Constant::Vertical: uLengths2[i] += uLengths1[i]+vpenalty; break; + switch ( Session::getDirection(i) ) { + case KbHorizontal: uLengths2[i] += uLengths1[i]+hpenalty; break; + case KbVertical: uLengths2[i] += uLengths1[i]+vpenalty; break; } } } @@ -874,13 +881,13 @@ namespace Katabatic { // Normalize: 0 < d < 1.0 (divide by H/V capacity). for ( size_t i=0 ; i<_depth ; i++ ) { - switch ( Session::getRoutingGauge()->getLayerDirection(i) ) { - case Constant::Horizontal: + switch ( Session::getDirection(i) ) { + case KbHorizontal: _densities [i] = ((float)uLengths2[i]) / ( hcapacity * (float)_box.getWidth() ); _feedthroughs [i] += (float)(_blockages[i] / _box.getWidth()); _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)_box.getWidth(); break; - case Constant::Vertical: + case KbVertical: _densities [i] = ((float)uLengths2[i]) / ( vcapacity * (float)_box.getHeight() ); _feedthroughs [i] += (float)(_blockages[i] / _box.getHeight()); _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)_box.getHeight(); @@ -960,13 +967,13 @@ namespace Katabatic { vector::const_iterator isegment; vector::const_iterator iend; - switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { - case Constant::Horizontal: + switch ( Session::getDirection(depth) ) { + case KbHorizontal: iend = _hsegments.end (); isegment = _hsegments.begin (); capacity = getHCapacity (); break; - case Constant::Vertical: + case KbVertical: iend = _vsegments.end (); isegment = _vsegments.begin (); capacity = getVCapacity (); @@ -985,9 +992,9 @@ namespace Katabatic { #endif float capacity = 0.0; - switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { - case Constant::Horizontal: capacity = getHCapacity(); break; - case Constant::Vertical: capacity = getVCapacity(); break; + switch ( Session::getDirection(depth) ) { + case KbHorizontal: capacity = getHCapacity(); break; + case KbVertical: capacity = getVCapacity(); break; } ltrace(200) << " | hasFreeTrack [" << getIndex() << "] depth:" << depth << " " @@ -1115,13 +1122,13 @@ namespace Katabatic { vector::iterator isegment; vector::iterator iend; - switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { - case Constant::Horizontal: + switch ( Session::getDirection(depth) ) { + case KbHorizontal: iend = _hsegments.end (); isegment = _hsegments.begin (); //capacity = getHCapacity (); break; - case Constant::Vertical: + case KbVertical: iend = _vsegments.end (); isegment = _vsegments.begin (); //capacity = getVCapacity (); @@ -1160,13 +1167,13 @@ namespace Katabatic { vector::iterator iend; set globalNets; - switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { - case Constant::Horizontal: + switch ( Session::getDirection(depth) ) { + case KbHorizontal: iend = _hsegments.end (); isegment = _hsegments.begin (); //capacity = getHCapacity (); break; - case Constant::Vertical: + case KbVertical: iend = _vsegments.end (); isegment = _vsegments.begin (); //capacity = getVCapacity (); @@ -1205,13 +1212,13 @@ namespace Katabatic { vector::iterator isegment; vector::iterator iend; - switch ( Session::getRoutingGauge()->getLayerDirection(depth) ) { - case Constant::Horizontal: + switch ( Session::getDirection(depth) ) { + case KbHorizontal: iend = _hsegments.end (); isegment = _hsegments.begin (); //capacity = getHCapacity (); break; - case Constant::Vertical: + case KbVertical: iend = _vsegments.end (); isegment = _vsegments.begin (); //capacity = getVCapacity (); diff --git a/katabatic/src/KatabaticEngine.cpp b/katabatic/src/KatabaticEngine.cpp index b87a7977..51f3964c 100644 --- a/katabatic/src/KatabaticEngine.cpp +++ b/katabatic/src/KatabaticEngine.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/katabatic/src/LayerAssign.cpp b/katabatic/src/LayerAssign.cpp index 70d00d53..16c76a53 100644 --- a/katabatic/src/LayerAssign.cpp +++ b/katabatic/src/LayerAssign.cpp @@ -49,7 +49,7 @@ namespace Katabatic { , unsigned long& total , unsigned long& globals ) { - if (depth+2 >= Session::getConfiguration()->getAllowedDepth()) { + if (depth+2 > Session::getConfiguration()->getAllowedDepth()) { cerr << Warning("Katabatic::_desaturate(): %s, no remaining upper layers." ,getString(Session::getRoutingGauge()->getRoutingLayer(depth)->getName()).c_str() ) << endl; @@ -467,44 +467,46 @@ namespace Katabatic { startMeasures(); Session::open( this ); - switch ( method ) { - case EngineLayerAssignByLength: _layerAssignByLength( total, global, globalNets ); break; - case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break; - case EngineNoNetLayerAssign: break; - default: - stopMeasures(); - Session::close(); - throw Error( badMethod - , "Katabatic::layerAssign()" - , method - , getString(_cell).c_str() - ); - } - - globalNets.clear(); - Session::revalidate(); - - if (getConfiguration()->getAllowedDepth() > 2) { - //for ( int i=0 ; i < 3 ; i++ ) { - for ( size_t depth=1 ; depth < getConfiguration()->getAllowedDepth()-2; ++depth ) { - _desaturate( depth, globalNets, total, global ); - if ( (depth > 1) and ((depth-1)%2 == 1) ) Session::revalidate(); - } - - globalNets.clear (); - - // if (not _gcellGrid->updateDensity()) break; - //} + if (Session::getAllowedDepth() >= 3) { + switch ( method ) { + case EngineLayerAssignByLength: _layerAssignByLength( total, global, globalNets ); break; + case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break; + case EngineNoNetLayerAssign: break; + default: + stopMeasures(); + Session::close(); + throw Error( badMethod + , "Katabatic::layerAssign()" + , method + , getString(_cell).c_str() + ); + } + + globalNets.clear(); Session::revalidate(); - } - + + if (getConfiguration()->getAllowedDepth() > 2) { + //for ( int i=0 ; i < 3 ; i++ ) { + for ( size_t depth=1 ; depth <= getConfiguration()->getAllowedDepth()-2; ++depth ) { + _desaturate( depth, globalNets, total, global ); + if ( (depth > 1) and ((depth-1)%2 == 1) ) Session::revalidate(); + } + + globalNets.clear (); + + // if (not _gcellGrid->updateDensity()) break; + //} + Session::revalidate(); + } + #if defined(CHECK_DATABASE) - _check( "after layer assignment" ); + _check( "after layer assignment" ); #endif - - Session::setKatabaticFlags( EngineWarnOnGCellOverload ); - _gcellGrid->checkDensity(); - + + Session::setKatabaticFlags( EngineWarnOnGCellOverload ); + _gcellGrid->checkDensity(); + } + Session::close(); stopMeasures(); diff --git a/katabatic/src/LoadGrByNet.cpp b/katabatic/src/LoadGrByNet.cpp index 27e02177..992b8397 100644 --- a/katabatic/src/LoadGrByNet.cpp +++ b/katabatic/src/LoadGrByNet.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -436,6 +436,9 @@ namespace { Point source; Point target; + size_t anchorDepth = Session::getLayerDepth( anchor->getLayer() ); + if (anchorDepth == 0) ++anchorDepth; + getPositions( anchor, source, target ); DbU::Unit width = abs( target.getX() - source.getX() ); @@ -443,9 +446,9 @@ namespace { unsigned int flags = 0; // HARDCODED VALUE. - flags |= (width < DbU::lambda(15.0)) ? HSmall : 0; - flags |= (height < DbU::lambda(15.0)) ? VSmall : 0; - flags |= ((width == 0) && (height == 0)) ? Punctual : 0; + flags |= (width < 3*Session::getPitch(anchorDepth)) ? HSmall : 0; + flags |= (height < 3*Session::getPitch(anchorDepth)) ? VSmall : 0; + flags |= ((width == 0) && (height == 0)) ? Punctual : 0; return flags; } @@ -957,7 +960,7 @@ namespace { } #endif // HARDCODED VALUE. - if ( (_topology & Global_Fixed) and (globalSegment->getLength() < DbU::lambda(100.0)) ) + if ( (_topology & Global_Fixed) and (globalSegment->getLength() < 2*DbU::lambda(50.0)) ) _toFixSegments.push_back( globalSegment ); if (_connexity.fields.globals < 2) { @@ -1013,7 +1016,9 @@ namespace { Point sourcePosition; Point targetPosition; const Layer* rpLayer = rp->getLayer(); - unsigned int direction = Session::getLayerDirection( rp->getLayer() ); + size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); + unsigned int direction = Session::getDirection ( rpDepth ); + DbU::Unit viaSide = Session::getWireWidth ( rpDepth ); getPositions( rp, sourcePosition, targetPosition ); @@ -1023,26 +1028,27 @@ namespace { GCell* sourceGCell = Session::getKatabatic()->getGCellGrid()->getGCell( sourcePosition ); GCell* targetGCell = Session::getKatabatic()->getGCellGrid()->getGCell( targetPosition ); - if (rp->getLayer() == Session::getRoutingLayer(0)) { + if (rpDepth == 0) { rpLayer = Session::getContactLayer(0); direction = KbHorizontal; + viaSide = Session::getViaWidth( rpDepth ); } // Non-M1 terminal or punctual M1 protections. - if ((rp->getLayer() != Session::getRoutingLayer(0)) or (sourcePosition == targetPosition)) { + if ((rpDepth != 0) or (sourcePosition == targetPosition)) { map::iterator irp = __routingPadAutoSegments.find( rp ); if (irp == __routingPadAutoSegments.end()) { AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell , rp , rpLayer , sourcePosition - , DbU::lambda(1.0), DbU::lambda(1.0) + , viaSide, viaSide ); AutoContact* targetProtect = AutoContactTerminal::create( targetGCell , rp , rpLayer , targetPosition - , DbU::lambda(1.0), DbU::lambda(1.0) + , viaSide, viaSide ); sourceProtect->setFlags( CntFixed ); targetProtect->setFlags( CntFixed ); @@ -1060,14 +1066,14 @@ namespace { , rp , rpLayer , sourcePosition - , DbU::lambda(1.0), DbU::lambda(1.0) + , viaSide, viaSide ); if (flags & DoTargetContact) target = AutoContactTerminal::create( targetGCell , rp , rpLayer , targetPosition - , DbU::lambda(1.0), DbU::lambda(1.0) + , viaSide, viaSide ); } @@ -1076,7 +1082,7 @@ namespace { , rp , rpLayer , rp->getCenter() - , DbU::lambda(1.0), DbU::lambda(1.0) + , viaSide, viaSide ); } @@ -1241,7 +1247,7 @@ namespace { , _routingPads[0] , Session::getContactLayer(3) , position - , DbU::lambda(1.0), DbU::lambda(1.0) + , Session::getViaWidth(3), Session::getViaWidth(3) ); source->setFlags( CntFixed ); @@ -1485,17 +1491,17 @@ namespace { AutoSegment::create( rpContact, _northEastContact, KbVertical ); } } else { + // All RoutingPad are M1. Component* southWestRp = _routingPads[0]; ltrace(99) << "| Initial S-W Global RP: " << southWestRp << endl; for ( unsigned int i=1 ; i<_routingPads.size() ; ++i ) { - if (southWestRp->getBoundingBox().getHeight() >= 4*DbU::lambda(5.0)) break; + if (southWestRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; if (_routingPads[i]->getBoundingBox().getHeight() > southWestRp->getBoundingBox().getHeight()) { ltrace(99) << "| Better RP: " << southWestRp << endl; southWestRp = _routingPads[i]; } } - // All RoutingPad are M1. if (_west and not _south) { _southWestContact = doRp_Access( _gcell, southWestRp, HAccess ); } else if (not _west and _south) { @@ -1514,7 +1520,7 @@ namespace { if (_routingPads.size() > 1) { unsigned int i=_routingPads.size()-2; do { - if (northEastRp->getBoundingBox().getHeight() >= 4*DbU::lambda(5.0)) break; + if (northEastRp->getBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; if (_routingPads[i]->getBoundingBox().getHeight() > northEastRp->getBoundingBox().getHeight()) { ltrace(99) << "| Better RP: " << northEastRp << endl; northEastRp = _routingPads[i]; @@ -1602,7 +1608,7 @@ namespace { if (flags & HAccess) { // HARDCODED VALUE. - if (_routingPads[0]->getBoundingBox().getHeight() < DbU::lambda(15)) { + if (_routingPads[0]->getBoundingBox().getHeight() < 3*Session::getPitch(1)) { AutoContact* subContact = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) ); AutoSegment::create( _southWestContact, subContact, KbVertical ); diff --git a/katabatic/src/PyKatabatic.cpp b/katabatic/src/PyKatabatic.cpp index 58b5d198..e53fd88f 100644 --- a/katabatic/src/PyKatabatic.cpp +++ b/katabatic/src/PyKatabatic.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2012-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/katabatic/src/Session.cpp b/katabatic/src/Session.cpp index 589e8e05..d3f3b4a4 100644 --- a/katabatic/src/Session.cpp +++ b/katabatic/src/Session.cpp @@ -315,10 +315,10 @@ namespace Katabatic { } - unsigned int Session::getLayerDirection ( const Layer* layer ) + unsigned int Session::getDirection ( size_t depth ) { RoutingGauge* rg = get("getDirection()")->_routingGauge; - switch ( rg->getLayerDirection(layer) ) { + switch ( rg->getLayerDirection(depth) ) { case Constant::Horizontal: return KbHorizontal; case Constant::Vertical: return KbVertical; } @@ -326,6 +326,33 @@ namespace Katabatic { } + DbU::Unit Session::_getPitch ( size_t depth, unsigned int flags ) const + { + if (flags == Configuration::NoFlags) return _routingGauge->getLayerPitch(depth); + + if (flags & Configuration::PitchAbove) { + if (depth < getAllowedDepth()) + return _routingGauge->getLayerPitch( depth + 1 ); + else { + if ( (depth > 0) and (_routingGauge->getLayerType(depth-1) != Constant::PinOnly) ) + return _routingGauge->getLayerPitch( depth - 1 ); + } + } + + if (flags & Configuration::PitchBelow) { + if ( (depth > 0) and (_routingGauge->getLayerType(depth-1) != Constant::PinOnly) ) + return _routingGauge->getLayerPitch( depth - 1 ); + else { + if (depth < getAllowedDepth()) + return _routingGauge->getLayerPitch( depth + 1 ); + } + } + + // Should issue at least a warning here. + return _routingGauge->getLayerPitch(depth); + } + + bool Session::isInDemoMode () { return get("isInDemoMode()")->_katabatic->isInDemoMode(); } @@ -346,18 +373,6 @@ namespace Katabatic { { get("setKabaticFlags()")->_katabatic->setFlags(flags); } - DbU::Unit Session::getExtensionCap () - { return getConfiguration()->getExtensionCap(); } - - - const Layer* Session::getRoutingLayer ( size_t depth ) - { return getConfiguration()->getRoutingLayer(depth); } - - - const Layer* Session::getContactLayer ( size_t depth ) - { return getConfiguration()->getContactLayer(depth); } - - void Session::link ( AutoContact* autoContact ) { return get("link(AutoContact*)")->_katabatic->_link( autoContact ); } diff --git a/katabatic/src/katabatic/AutoSegment.h b/katabatic/src/katabatic/AutoSegment.h index 58c673db..d03e3add 100644 --- a/katabatic/src/katabatic/AutoSegment.h +++ b/katabatic/src/katabatic/AutoSegment.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -20,8 +20,6 @@ #include #include #include -#include - #include "hurricane/Interval.h" #include "hurricane/Segment.h" #include "hurricane/Components.h" @@ -100,7 +98,7 @@ namespace Katabatic { , Revalidate = 0x000000004 }; public: - typedef std::tr1::function< void(AutoSegment*) > RevalidateCb_t; + typedef std::function< void(AutoSegment*) > RevalidateCb_t; public: static void setDestroyMode ( bool ); static AutoSegment* create ( AutoContact* source @@ -188,6 +186,8 @@ namespace Katabatic { AutoContact* getOppositeAnchor ( AutoContact* ) const; size_t getPerpandicularsBound ( set& ); inline AutoSegment* getParent () const; + inline unsigned int getDepth () const; + inline DbU::Unit getPitch () const; inline DbU::Unit getAxis () const; virtual DbU::Unit getSourceU () const = 0; virtual DbU::Unit getTargetU () const = 0; @@ -285,6 +285,7 @@ namespace Katabatic { GCell* _gcell; const unsigned long _id; unsigned int _flags; + unsigned int _depth : 8; unsigned int _optimalMin : 8; unsigned int _optimalMax : 8; DbU::Unit _sourcePosition; @@ -386,6 +387,8 @@ namespace Katabatic { inline AutoContact* AutoSegment::getAutoTarget () const { return Session::lookup(getTarget()); } inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); } inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); } + inline unsigned int AutoSegment::getDepth () const { return _depth; } + inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Configuration::NoFlags); } inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); } inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getY():_gcell->getX(); } inline DbU::Unit AutoSegment::getExtremity () const { return isHorizontal()?_gcell->getYMax():_gcell->getXMax(); } @@ -422,7 +425,7 @@ namespace Katabatic { inline unsigned int AutoSegment::getFlags () const { return _flags; } inline unsigned int AutoSegment::_getFlags () const { return _flags; } - inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); } + inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); } inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); } inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); } //inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); } diff --git a/katabatic/src/katabatic/ChipTools.h b/katabatic/src/katabatic/ChipTools.h index 84839e38..a8cdea8a 100644 --- a/katabatic/src/katabatic/ChipTools.h +++ b/katabatic/src/katabatic/ChipTools.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -51,6 +50,8 @@ namespace Katabatic { inline const Torus& getCorona () const; inline bool intersectVPads ( const Box& ) const; inline bool intersectHPads ( const Box& ) const; + inline bool vPadsEnclosed ( const Box& ) const; + inline bool hPadsEnclosed ( const Box& ) const; public: Record* _getRecord () const; std::string _getString () const; @@ -86,6 +87,12 @@ namespace Katabatic { inline bool ChipTools::intersectHPads ( const Box& box ) const { return _topPadsBb.intersect(box) or _bottomPadsBb.intersect(box); } + inline bool ChipTools::vPadsEnclosed ( const Box& box ) const + { return _leftPadsBb.contains(box) or _rightPadsBb.contains(box); } + + inline bool ChipTools::hPadsEnclosed ( const Box& box ) const + { return _topPadsBb.contains(box) or _bottomPadsBb.contains(box); } + } // Katabatic namespace. diff --git a/katabatic/src/katabatic/Configuration.h b/katabatic/src/katabatic/Configuration.h index 829c9e88..d1107fa3 100644 --- a/katabatic/src/katabatic/Configuration.h +++ b/katabatic/src/katabatic/Configuration.h @@ -1,7 +1,7 @@ // -*- mode: C++; explicit-buffer-name: "Configuration.h" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -36,6 +36,7 @@ namespace Katabatic { using std::string; using Hurricane::Record; + using Hurricane::Name; using Hurricane::Layer; using Hurricane::DbU; using Hurricane::Cell; @@ -48,6 +49,8 @@ namespace Katabatic { class Configuration { + public: + enum Flag { NoFlags=0x0000, PitchAbove=0x0001, PitchBelow=0x0002 }; public: // Constructor & Destructor. virtual ~Configuration (); @@ -63,6 +66,14 @@ namespace Katabatic { virtual const Layer* getRoutingLayer ( size_t depth ) const = 0; virtual Layer* getContactLayer ( size_t depth ) const = 0; virtual DbU::Unit getExtensionCap () const = 0; + virtual DbU::Unit getPitch ( size_t depth, unsigned int flags ) const = 0; + virtual DbU::Unit getOffset ( size_t depth ) const = 0; + virtual DbU::Unit getWireWidth ( size_t depth ) const = 0; + virtual unsigned int getDirection ( size_t depth ) const = 0; + virtual DbU::Unit getPitch ( const Layer*, unsigned int flags ) const = 0; + virtual DbU::Unit getOffset ( const Layer* ) const = 0; + virtual DbU::Unit getWireWidth ( const Layer* ) const = 0; + virtual unsigned int getDirection ( const Layer* ) const = 0; virtual float getSaturateRatio () const = 0; virtual size_t getSaturateRp () const = 0; virtual DbU::Unit getGlobalThreshold () const = 0; @@ -108,6 +119,14 @@ namespace Katabatic { virtual const Layer* getRoutingLayer ( size_t depth ) const; virtual Layer* getContactLayer ( size_t depth ) const; virtual DbU::Unit getExtensionCap () const; + virtual DbU::Unit getPitch ( size_t depth, unsigned int flags ) const; + virtual DbU::Unit getOffset ( size_t depth ) const; + virtual DbU::Unit getWireWidth ( size_t depth ) const; + virtual unsigned int getDirection ( size_t depth ) const; + virtual DbU::Unit getPitch ( const Layer*, unsigned int flags ) const; + virtual DbU::Unit getOffset ( const Layer* ) const; + virtual DbU::Unit getWireWidth ( const Layer* ) const; + virtual unsigned int getDirection ( const Layer* ) const; virtual float getSaturateRatio () const; virtual size_t getSaturateRp () const; virtual DbU::Unit getGlobalThreshold () const; @@ -137,6 +156,7 @@ namespace Katabatic { private: ConfigurationConcrete ( const ConfigurationConcrete& ); ConfigurationConcrete& operator= ( const ConfigurationConcrete& ); + void _setTopRoutingLayer ( Name name ); }; diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index df47ba4b..7270f194 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/katabatic/src/katabatic/Session.h b/katabatic/src/katabatic/Session.h index 6a8c358d..b9f0902b 100644 --- a/katabatic/src/katabatic/Session.h +++ b/katabatic/src/katabatic/Session.h @@ -1,7 +1,7 @@ // -*- mode: C++; explicit-buffer-name: "Session.h" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -24,7 +24,9 @@ #include #include "hurricane/Commons.h" #include "hurricane/DbU.h" +#include "crlcore/RoutingGauge.h" #include "katabatic/Constants.h" +#include "katabatic/Configuration.h" namespace Hurricane { class Layer; @@ -34,14 +36,9 @@ namespace Hurricane { class Segment; } -namespace CRL { - class RoutingGauge; -} - namespace Katabatic { - using std::cerr; using std::endl; using std::string; @@ -61,7 +58,6 @@ namespace Katabatic { using Hurricane::Segment; using CRL::RoutingGauge; - class Configuration; class AutoContact; class AutoSegment; class KatabaticEngine; @@ -82,13 +78,27 @@ namespace Katabatic { static inline Technology* getTechnology (); static inline KatabaticEngine* getKatabatic (); static inline const Configuration* getConfiguration (); - static inline RoutingGauge* getRoutingGauge (); - static unsigned int getLayerDirection ( const Layer* ); static float getSaturateRatio (); static size_t getSaturateRp (); + static inline size_t getAllowedDepth (); static DbU::Unit getExtensionCap (); - static const Layer* getRoutingLayer ( size_t ); - static const Layer* getContactLayer ( size_t ); + static inline RoutingGauge* getRoutingGauge (); + static inline RoutingLayerGauge* getLayerGauge ( size_t depth ); + static inline size_t getDepth (); + static inline size_t getViaDepth ( const Layer* layer ); + static inline size_t getLayerDepth ( const Layer* layer ); + static inline const Layer* getRoutingLayer ( size_t ); + static inline const Layer* getContactLayer ( size_t ); + static unsigned int getDirection ( size_t depth ); + static inline DbU::Unit getPitch ( size_t depth, unsigned int flags ); + static inline DbU::Unit getOffset ( size_t depth ); + static inline DbU::Unit getWireWidth ( size_t depth ); + static inline DbU::Unit getViaWidth ( size_t depth ); + static inline unsigned int getDirection ( const Layer* ); + static inline DbU::Unit getPitch ( const Layer*, unsigned int flags ); + static inline DbU::Unit getOffset ( const Layer* ); + static inline DbU::Unit getWireWidth ( const Layer* ); + static inline DbU::Unit getViaWidth ( const Layer* ); static inline size_t getSegmentStackSize (); static inline size_t getContactStackSize (); static inline const vector& getInvalidateds (); @@ -128,6 +138,7 @@ namespace Katabatic { void _canonize (); void _revalidateTopology (); size_t _revalidate (); + DbU::Unit _getPitch ( size_t depth, unsigned int flags ) const; Record* _getRecord () const; string _getString () const; inline string _getTypeName () const; @@ -181,6 +192,25 @@ namespace Katabatic { inline void Session::dogleg ( AutoSegment* autoSegment ) { return get("dogleg(AutoSegment*)")->_dogleg(autoSegment); } inline void Session::destroyRequest ( AutoSegment* autoSegment ) { return get("destroyRequest(AutoSegment*)")->_destroyRequest(autoSegment); } + inline DbU::Unit Session::getExtensionCap () { return getConfiguration()->getExtensionCap(); } + inline size_t Session::getAllowedDepth () { return getConfiguration()->getAllowedDepth(); } + + inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); } + inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); } + inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); } + inline size_t Session::getLayerDepth ( const Layer* layer ) { return getRoutingGauge()->getLayerDepth(layer); } + inline const Layer* Session::getRoutingLayer ( size_t depth ) { return getRoutingGauge()->getRoutingLayer(depth); } + inline const Layer* Session::getContactLayer ( size_t depth ) { return getRoutingGauge()->getContactLayer(depth); } + inline DbU::Unit Session::getPitch ( unsigned int depth, unsigned int flags=Configuration::NoFlags ) { return get("getPitch(depth,flags)")->_getPitch( depth, flags ); } + inline DbU::Unit Session::getOffset ( size_t depth ) { return getRoutingGauge()->getLayerOffset(depth); } + inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); } + inline DbU::Unit Session::getViaWidth ( size_t depth ) { return getRoutingGauge()->getViaWidth(depth); } + inline DbU::Unit Session::getPitch ( const Layer* layer, unsigned int flags=Configuration::NoFlags ) { return getPitch( getLayerDepth(layer), flags ); } + inline DbU::Unit Session::getOffset ( const Layer* layer ) { return getOffset ( getLayerDepth(layer) ); } + inline DbU::Unit Session::getWireWidth ( const Layer* layer ) { return getWireWidth( getLayerDepth(layer) ); } + inline DbU::Unit Session::getViaWidth ( const Layer* layer ) { return getViaWidth ( getViaDepth(layer) ); } + inline unsigned int Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); } + inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); } inline void Session::_doglegReset () { _doglegs.clear(); } inline void Session::_invalidate ( AutoContact* contact ) { _autoContacts.push_back(contact); } diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index 2f002ab8..9a09e263 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -24,6 +24,7 @@ #include "hurricane/RegularLayer.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" +#include "hurricane/RoutingPad.h" #include "hurricane/NetExternalComponents.h" #include "hurricane/Instance.h" #include "hurricane/Plug.h" @@ -51,6 +52,7 @@ namespace { using Hurricane::Interval; using Hurricane::Horizontal; using Hurricane::Vertical; + using Hurricane::RoutingPad; using Hurricane::NetExternalComponents; using Hurricane::Instance; using Hurricane::Plug; @@ -69,6 +71,27 @@ namespace { using namespace Kite; +// ------------------------------------------------------------------- +// Local Functions. + + void destroyRing ( Net* net ) + { + forEach ( RoutingPad*, irp, net->getRoutingPads() ) { + bool allMasters = true; + vector ring; + forEach ( Hook*, ihook, irp->getBodyHook()->getHooks() ) { + if (not ihook->isMaster()) { allMasters = false; break; } + ring.push_back( *ihook ); + } + if (allMasters) { + for ( auto ihook : ring ) { + ihook->_setNextHook( ihook ); + } + } + } + } + + // ------------------------------------------------------------------- // Class : "::GlobalNetTable". @@ -82,9 +105,11 @@ namespace { inline Net* getVssi () const; inline Net* getCk () const; inline Net* getCki () const; - inline Net* getCkc () const; + inline Net* getCko () const; inline Net* getBlockage () const; inline void setBlockage ( Net* ); + private: + bool guessGlobalNet ( const Name&, Net* ); private: Name _vddeName; Name _vddiName; @@ -92,14 +117,14 @@ namespace { Name _vssiName; Name _ckName; Name _ckiName; - Name _ckcName; + Name _ckoName; Net* _vdde; Net* _vddi; Net* _vsse; Net* _vssi; Net* _ck; // Clock net on the (external) pad. Net* _cki; // Clock net in the pad ring. - Net* _ckc; // Clock net of the core (design). + Net* _cko; // Clock net of the core (design). Net* _blockage; }; @@ -110,7 +135,7 @@ namespace { inline Net* GlobalNetTable::getVssi () const { return _vssi; } inline Net* GlobalNetTable::getCk () const { return _ck; } inline Net* GlobalNetTable::getCki () const { return _cki; } - inline Net* GlobalNetTable::getCkc () const { return _ckc; } + inline Net* GlobalNetTable::getCko () const { return _cko; } inline Net* GlobalNetTable::getBlockage () const { return _blockage; } inline void GlobalNetTable::setBlockage ( Net* net ) { _blockage=net; } @@ -119,16 +144,16 @@ namespace { , _vddiName("vddi") , _vsseName("vsse") , _vssiName("vssi") - , _ckName ("ck") - , _ckiName ("cki") - , _ckcName ("ckc") + , _ckName ("pad" ) + , _ckiName ("ck" ) + , _ckoName ("cko" ) , _vdde (NULL) , _vddi (NULL) , _vsse (NULL) , _vssi (NULL) , _ck (NULL) , _cki (NULL) - , _ckc (NULL) + , _cko (NULL) , _blockage(NULL) { if ( topCell == NULL ) return; @@ -137,77 +162,125 @@ namespace { bool hasPad = false; forEach ( Instance*, iinstance, topCell->getInstances() ) { - if ( af->isPad(iinstance->getMasterCell()) ) { - cmess1 << " o Design has pads, assuming complete chip top structure." << endl; - hasPad = true; - break; - } - } - - forEach ( Net*, inet, topCell->getNets() ) { - Net::Type netType = inet->getType(); - if ( (netType != Net::Type::POWER ) - and (netType != Net::Type::GROUND) - and (netType != Net::Type::CLOCK ) ) continue; - if ( not inet->isGlobal() ) { - cerr << Warning("Non global supply/clock net <%s>.",getString(inet->getName()).c_str()) << endl; - } - - if ( hasPad and (inet->getName() == _vddeName) ) { _vdde = *inet; continue; } - else if ( hasPad and (inet->getName() == _vsseName) ) { _vsse = *inet; continue; } - else if ( hasPad and (inet->getName() == _ckName ) ) { _ck = *inet; continue; } - else if ( hasPad and (inet->getName() == _ckiName ) ) { _cki = *inet; continue; } - - if ( inet->isPower() ) { - if ( _vddi == NULL ) { - cmess1 << " - Using <" << inet->getName() << "> as core power net." << endl; - _vddi = *inet; - } else { - cerr << Error("More than one power net in designs is not supported yet.\n" - " (<%s> and <%s>)" - ,getString(_vddi->getName()).c_str() - ,getString(inet->getName()).c_str() - ) << endl; + if (af->isPad(iinstance->getMasterCell())) { + if (not hasPad) { + cmess1 << " o Design has pads, assuming complete chip top structure." << endl; + hasPad = true; } - } - if ( inet->isGround() ) { - if ( _vssi == NULL ) { - cmess1 << " - Using <" << inet->getName() << "> as core ground net." << endl; - _vssi = *inet; - } else { - cerr << Error("More than one ground net in designs is not supported yet.\n" - " (<%s> and <%s>)" - ,getString(_vssi->getName()).c_str() - ,getString(inet->getName()).c_str() - ) << endl; + if (iinstance->getMasterCell()->getName() == Name("pvddeck_px")) { + cmess1 << " o Reference power pad: " << iinstance->getName() + << "(model:" << iinstance->getMasterCell()->getName() << ")." << endl; + + // Guessing the power, ground and clock nets from *this* pad connexions. + forEach ( Plug*, iplug, iinstance->getPlugs() ) { + Net* masterNet = iplug->getMasterNet(); + Net::Type netType = masterNet->getType(); + if ( (netType != Net::Type::POWER ) + and (netType != Net::Type::GROUND) + and (netType != Net::Type::CLOCK ) ) continue; + + Net* net = iplug->getNet(); + if (not net) { + net = topCell->getNet( masterNet->getName() ); + if (not net) { + cerr << Error("Missing global net <%s> at chip level.",getString(masterNet->getName()).c_str()) << endl; + continue; + } + } + + guessGlobalNet( masterNet->getName(), net ); + } } - } - if ( inet->isClock() ) { - if ( _ckc == NULL ) { - cmess1 << " - Using <" << inet->getName() << "> as core clock net." << endl; - _ckc = *inet; - } else { - cerr << Error("More than one clock net in designs is not supported yet.\n" - " (<%s> and <%s>)" - ,getString(_ckc->getName()).c_str() - ,getString(inet->getName()).c_str() - ) << endl; + if (iinstance->getMasterCell()->getName() == Name("pck_px")) { + cmess1 << " o Reference clock pad: " << iinstance->getName() + << "(model:" << iinstance->getMasterCell()->getName() << ")." << endl; + + // Guessing external clock net *only* from *this* pad connexions. + forEach ( Plug*, iplug, iinstance->getPlugs() ) { + Net* masterNet = iplug->getMasterNet(); + Net* net = iplug->getNet(); + if (not net) { + net = topCell->getNet( masterNet->getName() ); + if (not net) { + cerr << Error("Missing global net <%s> at chip level.",getString(masterNet->getName()).c_str()) << endl; + continue; + } + } + + if (masterNet->getName() == _ckName) { + cmess1 << " - Using <" << net->getName() << "> as external chip clock net." << endl; + _ck = net; + } + } } } } - if ( hasPad ) { - if ( _vdde == NULL ) cerr << Error("Missing (pad) net at chip level." ) << endl; - if ( _vsse == NULL ) cerr << Error("Missing (pad) net at chip level." ) << endl; - if ( _ck == NULL ) cerr << Warning("No (pad) net at chip level." ) << endl; - if ( _cki == NULL ) cerr << Warning("No (pad) net at chip level." ) << endl; + if (hasPad) { + if (_vdde == NULL) cerr << Error("Missing net (for pads) at chip level." ) << endl; + else destroyRing( _vdde ); + if (_vsse == NULL) cerr << Error("Missing net (for pads) at chip level." ) << endl; + else destroyRing( _vsse ); + if (_ck == NULL) cerr << Warning("No net at (for pads) chip level." ) << endl; + if (_cki == NULL) cerr << Warning("No net at (for pads) chip level." ) << endl; + else destroyRing( _cki ); } - if ( _vddi == NULL ) cerr << Error("Missing / net at top level." ) << endl; - if ( _vssi == NULL ) cerr << Error("Missing / net at top level." ) << endl; - if ( _ckc == NULL ) cparanoid << Warning("No net at top level." ) << endl; + if (_vddi == NULL) cerr << Error("Missing / net (for pads) at top level." ) << endl; + else destroyRing( _vddi ); + if (_vssi == NULL) cerr << Error("Missing / net (for pads) at top level." ) << endl; + else destroyRing( _vssi ); + if (_cko == NULL) cparanoid << Warning("No net at top level." ) << endl; + } + + + bool GlobalNetTable::guessGlobalNet ( const Name& name, Net* net ) + { + if (name == _vddeName) { + cmess1 << " - Using <" << net->getName() << "> as corona (external:vdde) power net." << endl; + _vdde = net; + return true; + } + + if (name == _vddiName) { + cmess1 << " - Using <" << net->getName() << "> as core (internal:vddi) power net." << endl; + _vddi = net; + return true; + } + + if (name == _vsseName) { + cmess1 << " - Using <" << net->getName() << "> as corona (external:vsse) ground net." << endl; + _vsse = net; + return true; + } + + if (name == _vssiName) { + cmess1 << " - Using <" << net->getName() << "> as core (internal:vssi) ground net." << endl; + _vssi = net; + return true; + } + + if (name == _ckiName) { + cmess1 << " - Using <" << net->getName() << "> as corona (external:cki) clock net." << endl; + _cki = net; + return true; + } + + if (name == _ckoName) { + cmess1 << " - Using <" << net->getName() << "> as core (internal:cko) clock net." << endl; + _cko = net; + return true; + } + + if (name == _ckName) { + cmess1 << " - Using <" << net->getName() << "> as external chip clock net." << endl; + _ck = net; + return true; + } + + return false; } @@ -247,7 +320,7 @@ namespace { if ( upNet->getName() == _ckName ) return _ck; if ( upNet->getName() == _ckiName ) return _cki; - if ( upNet->getName() == _ckcName ) return _ckc; + if ( upNet->getName() == _ckoName ) return _cko; return NULL; } @@ -860,6 +933,8 @@ namespace { setArea ( kite->getCell()->getBoundingBox() ); setBasicLayer ( NULL ); setFilter ( Query::DoTerminalCells|Query::DoComponents ); + + cmess1 << " o Building power rails." << endl; } @@ -1043,8 +1118,6 @@ namespace Kite { void KiteEngine::buildPowerRails () { - cmess1 << " o Building power rails." << endl; - if (not _blockageNet) { _blockageNet = getCell()->getNet("blockagenet"); if (not _blockageNet) diff --git a/kite/src/Configuration.cpp b/kite/src/Configuration.cpp index 4ca4f1fa..a5927e86 100644 --- a/kite/src/Configuration.cpp +++ b/kite/src/Configuration.cpp @@ -40,15 +40,14 @@ namespace Kite { Configuration::Configuration ( Katabatic::Configuration* base ) : Katabatic::Configuration() - , _base (base) - , _postEventCb () - , _edgeCapacityPercent(Cfg::getParamPercentage("kite.edgeCapacity", 80.0)->asDouble()) - , _expandStep (Cfg::getParamPercentage("kite.expandStep" ,100.0)->asDouble()) - , _ripupLimits () - , _ripupCost (Cfg::getParamInt("kite.ripupCost" , 3)->asInt()) - , _eventsLimit (Cfg::getParamInt("kite.eventsLimit" ,4000000)->asInt()) + , _base (base) + , _postEventCb () + , _hEdgeCapacityPercent(Cfg::getParamPercentage("kite.hEdgeCapacity", 80.0)->asDouble()) + , _vEdgeCapacityPercent(Cfg::getParamPercentage("kite.vEdgeCapacity", 80.0)->asDouble()) + , _ripupLimits () + , _ripupCost (Cfg::getParamInt("kite.ripupCost" , 3)->asInt()) + , _eventsLimit (Cfg::getParamInt("kite.eventsLimit" ,4000000)->asInt()) { - _ripupLimits[BorderRipupLimit] = Cfg::getParamInt("kite.borderRipupLimit" ,26)->asInt(); _ripupLimits[StrapRipupLimit] = Cfg::getParamInt("kite.strapRipupLimit" ,16)->asInt(); _ripupLimits[LocalRipupLimit] = Cfg::getParamInt("kite.localRipupLimit" , 7)->asInt(); _ripupLimits[GlobalRipupLimit] = Cfg::getParamInt("kite.globalRipupLimit" , 5)->asInt(); @@ -77,17 +76,16 @@ namespace Kite { Configuration::Configuration ( const Configuration& other, Katabatic::Configuration* base ) : Katabatic::Configuration() - , _base (base) - , _postEventCb (other._postEventCb) - , _edgeCapacityPercent(other._edgeCapacityPercent) - , _expandStep (other._expandStep) - , _ripupLimits () - , _ripupCost (other._ripupCost) - , _eventsLimit (other._eventsLimit) + , _base (base) + , _postEventCb (other._postEventCb) + , _hEdgeCapacityPercent(other._hEdgeCapacityPercent) + , _vEdgeCapacityPercent(other._vEdgeCapacityPercent) + , _ripupLimits () + , _ripupCost (other._ripupCost) + , _eventsLimit (other._eventsLimit) { if ( _base == NULL ) _base = other._base->clone(); - _ripupLimits[BorderRipupLimit] = other._ripupLimits[BorderRipupLimit]; _ripupLimits[StrapRipupLimit] = other._ripupLimits[StrapRipupLimit]; _ripupLimits[LocalRipupLimit] = other._ripupLimits[LocalRipupLimit]; _ripupLimits[GlobalRipupLimit] = other._ripupLimits[GlobalRipupLimit]; @@ -143,6 +141,38 @@ namespace Kite { { return _base->getContactLayer(depth); } + DbU::Unit Configuration::getPitch ( size_t depth, unsigned int flags ) const + { return _base->getPitch(depth,flags); } + + + DbU::Unit Configuration::getOffset ( size_t depth ) const + { return _base->getOffset(depth); } + + + DbU::Unit Configuration::getWireWidth ( size_t depth ) const + { return _base->getWireWidth(depth); } + + + unsigned int Configuration::getDirection ( size_t depth ) const + { return _base->getDirection(depth); } + + + DbU::Unit Configuration::getPitch ( const Layer* layer, unsigned int flags ) const + { return _base->getPitch(layer,flags); } + + + DbU::Unit Configuration::getOffset ( const Layer* layer ) const + { return _base->getOffset(layer); } + + + DbU::Unit Configuration::getWireWidth ( const Layer* layer ) const + { return _base->getWireWidth(layer); } + + + unsigned int Configuration::getDirection ( const Layer* layer ) const + { return _base->getDirection(layer); } + + DbU::Unit Configuration::getExtensionCap () const { return _base->getExtensionCap(); } @@ -194,13 +224,23 @@ namespace Kite { } - void Configuration::setEdgeCapacityPercent ( float percent ) + void Configuration::setHEdgeCapacityPercent ( float percent ) { - if ( percent > 1.0 ) - throw Error("Configuration::setEdgeCapacityPercent(): edge capacity ratio greater than 1.0 (%.1f)." - ,percent); + if (percent > 1.0) + throw Error( "Configuration::setHEdgeCapacityPercent(): edge capacity ratio greater than 1.0 (%.1f)." + , percent ); - _edgeCapacityPercent = percent; + _hEdgeCapacityPercent = percent; + } + + + void Configuration::setVEdgeCapacityPercent ( float percent ) + { + if (percent > 1.0) + throw Error( "Configuration::setVEdgeCapacityPercent(): edge capacity ratio greater than 1.0 (%.1f)." + , percent ); + + _vEdgeCapacityPercent = percent; } @@ -218,10 +258,9 @@ namespace Kite { void Configuration::print ( Cell* cell ) const { cout << " o Configuration of ToolEngine for Cell <" << cell->getName() << ">" << endl; - cout << Dots::asPercentage(" - Global router edge capacity" ,_edgeCapacityPercent) << endl; - cout << Dots::asPercentage(" - GCell aggregation threshold (delta)",_expandStep) << endl; + cout << Dots::asPercentage(" - Global router H edge capacity" ,_hEdgeCapacityPercent) << endl; + cout << Dots::asPercentage(" - Global router V edge capacity" ,_vEdgeCapacityPercent) << endl; cout << Dots::asULong (" - Events limit (iterations)" ,_eventsLimit) << endl; - cout << Dots::asUInt (" - Ripup limit, borders" ,_ripupLimits[BorderRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, straps" ,_ripupLimits[StrapRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, locals" ,_ripupLimits[LocalRipupLimit]) << endl; cout << Dots::asUInt (" - Ripup limit, globals" ,_ripupLimits[GlobalRipupLimit]) << endl; @@ -250,10 +289,10 @@ namespace Kite { Record* record = _base->_getRecord(); //record->add ( getSlot ( "_rg" , _rg ) ); if ( record ) { - record->add ( getSlot("_edgeCapacityPercent",_edgeCapacityPercent) ); - record->add ( getSlot("_ripupCost" ,_ripupCost ) ); - record->add ( getSlot("_eventsLimit" ,_eventsLimit ) ); - record->add ( getSlot("_edgeCapacityPercent",_edgeCapacityPercent) ); + record->add ( getSlot("_hEdgeCapacityPercent" ,_hEdgeCapacityPercent ) ); + record->add ( getSlot("_vEdgeCapacityPercent" ,_vEdgeCapacityPercent ) ); + record->add ( getSlot("_ripupCost" ,_ripupCost ) ); + record->add ( getSlot("_eventsLimit" ,_eventsLimit ) ); record->add ( getSlot("_ripupLimits[StrapRipupLimit]" ,_ripupLimits[StrapRipupLimit] ) ); record->add ( getSlot("_ripupLimits[LocalRipupLimit]" ,_ripupLimits[LocalRipupLimit] ) ); diff --git a/kite/src/DataNegociate.cpp b/kite/src/DataNegociate.cpp index 33907dff..8e2f642c 100644 --- a/kite/src/DataNegociate.cpp +++ b/kite/src/DataNegociate.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/kite/src/GraphicKiteEngine.cpp b/kite/src/GraphicKiteEngine.cpp index 2065e339..0db01d5e 100644 --- a/kite/src/GraphicKiteEngine.cpp +++ b/kite/src/GraphicKiteEngine.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,7 +14,6 @@ // +-----------------------------------------------------------------+ -#include #include #include #include @@ -33,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +49,7 @@ namespace Kite { using namespace std; using Hurricane::Error; using Hurricane::Warning; + using Hurricane::Exception; using Hurricane::Breakpoint; using Hurricane::DebugSession; using Hurricane::UpdateSession; @@ -58,6 +58,7 @@ namespace Kite { using Hurricane::Graphics; using Hurricane::ColorScale; using Hurricane::ControllerWidget; + using Hurricane::ExceptionWidget; using CRL::Catalog; using CRL::AllianceFramework; using Knik::KnikEngine; @@ -123,6 +124,7 @@ namespace Kite { if (not kite) { kite = KiteEngine::create( cell ); kite->setPostEventCb( boost::bind(&GraphicKiteEngine::postEvent,this) ); + kite->setViewer( _viewer ); } else cerr << Warning( "%s already has a Kite engine.", getString(cell).c_str() ) << endl; @@ -130,86 +132,84 @@ namespace Kite { } - KiteEngine* GraphicKiteEngine::getForFramework () + KiteEngine* GraphicKiteEngine::getForFramework ( unsigned int flags ) { // Currently, only one framework is avalaible: Alliance. KiteEngine* kite = KiteEngine::get( getCell() ); if (kite) return kite; - kite = createEngine(); - - if (not kite) - throw Error( "Failed to create Kite engine on %s.", getString(getCell()).c_str() ); + if (flags & CreateEngine) { + kite = createEngine(); + if (not kite) + throw Error( "Failed to create Kite engine on %s.", getString(getCell()).c_str() ); + } else { + throw Error( "KiteEngine not created yet, run the global router first." ); + } return kite; } - void GraphicKiteEngine::saveGlobalSolution () + void GraphicKiteEngine::_loadGlobalSolution () + { + KiteEngine* kite = getForFramework( CreateEngine ); + kite->runGlobalRouter( KtLoadGlobalRouting ); + } + + + void GraphicKiteEngine::_saveGlobalSolution () { KiteEngine* kite = KiteEngine::get( getCell() ); if (kite) kite->saveGlobalSolution (); } - void GraphicKiteEngine::loadGlobalSolution () + void GraphicKiteEngine::_globalRoute () { - KiteEngine* kite = getForFramework(); - - emit cellPreModificated(); - kite->runGlobalRouter( KtLoadGlobalRouting ); - emit cellPostModificated(); - } - - - void GraphicKiteEngine::globalRoute () - { - KiteEngine* kite = getForFramework(); - - emit cellPreModificated(); + KiteEngine* kite = getForFramework( CreateEngine ); kite->runGlobalRouter( KtBuildGlobalRouting ); - emit cellPostModificated(); } - void GraphicKiteEngine::detailRoute () + void GraphicKiteEngine::_loadGlobalRouting () { static KatabaticEngine::NetSet routingNets; - KiteEngine* kite = KiteEngine::get( getCell() ); - if (not kite) { - throw Error( "KiteEngine not created yet, run the global router first." ); - } + KiteEngine* kite = getForFramework( NoFlags ); if (cmess1.enabled()) kite->printConfiguration(); - emit cellPreModificated(); _viewer->clearToolInterrupt(); kite->loadGlobalRouting( Katabatic::EngineLoadGrByNet, routingNets ); - emit cellPostModificated(); - emit cellPreModificated (); - kite->balanceGlobalDensity (); - kite->layerAssign ( Katabatic::EngineNoNetLayerAssign ); - emit cellPostModificated(); - emit cellPreModificated(); - kite->runNegociate(); - emit cellPostModificated(); } - void GraphicKiteEngine::finalize () + void GraphicKiteEngine::_balanceGlobalDensity () { - emit cellPreModificated(); - KiteEngine* kite = KiteEngine::get( getCell() ); + KiteEngine* kite = getForFramework( NoFlags ); + kite->balanceGlobalDensity (); + kite->layerAssign ( Katabatic::EngineNoNetLayerAssign ); + } + + + void GraphicKiteEngine::_runNegociate () + { + KiteEngine* kite = getForFramework( NoFlags ); + kite->runNegociate(); + } + + + void GraphicKiteEngine::_finalize () + { + KiteEngine* kite = getForFramework( NoFlags ); if (kite) { kite->finalizeLayout(); kite->destroy(); } - emit cellPostModificated(); } - void GraphicKiteEngine::save () + void GraphicKiteEngine::_save () { Cell* cell = getCell(); AllianceFramework* af = AllianceFramework::get(); @@ -220,6 +220,34 @@ namespace Kite { } + void GraphicKiteEngine::globalRoute () + { ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_globalRoute,this) ); } + + + void GraphicKiteEngine::loadGlobalSolution () + { ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_loadGlobalSolution,this) ); } + + + void GraphicKiteEngine::saveGlobalSolution () + { ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_saveGlobalSolution,this) ); } + + + void GraphicKiteEngine::detailRoute () + { + ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_loadGlobalRouting ,this) ); + ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_balanceGlobalDensity,this) ); + ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_runNegociate ,this) ); + } + + + void GraphicKiteEngine::finalize () + { ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_finalize,this) ); } + + + void GraphicKiteEngine::save () + { ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_save,this) ); } + + void GraphicKiteEngine::route () { globalRoute(); @@ -230,7 +258,7 @@ namespace Kite { void GraphicKiteEngine::dumpMeasures () { - KiteEngine* kite = getForFramework(); + KiteEngine* kite = getForFramework( NoFlags ); if (kite) kite->dumpMeasures(); } @@ -337,9 +365,6 @@ namespace Kite { connect( dDumpMeasuresAction, SIGNAL(triggered()), this, SLOT(dumpMeasures ()) ); connect( routeAction , SIGNAL(triggered()), this, SLOT(route ()) ); } - - connect( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) ); - connect( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) ); } diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index 5a07c6b3..5401eb89 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -101,6 +101,7 @@ namespace Kite { KiteEngine::KiteEngine ( Cell* cell ) : KatabaticEngine (cell) + , _viewer (NULL) , _knik (NULL) , _blockageNet (NULL) , _configuration (new Configuration(getKatabaticConfiguration())) @@ -238,10 +239,16 @@ namespace Kite { unsigned int flags = Cell::WarnOnUnplacedInstances; flags |= (mode & KtBuildGlobalRouting) ? Cell::BuildRings : 0; cell->flattenNets( flags ); + + // Test signals from . + //DebugSession::addToTrace( getCell(), "core.snx_inst.a2_x2_8_sig" ); + //DebugSession::addToTrace( getCell(), "m_clock" ); + //DebugSession::addToTrace( getCell(), "a2_x2_8_sig" ); KatabaticEngine::chipPrep(); - KnikEngine::setEdgeCapacityPercent( 1.0 ); + KnikEngine::setHEdgeCapacityPercent( 1.0 ); + KnikEngine::setVEdgeCapacityPercent( 1.0 ); _knik = KnikEngine::create( cell , 1 // _congestion , 2 // _preCongestion @@ -249,37 +256,39 @@ namespace Kite { , true // _useSegments , 2.5 // _edgeCost ); + _knik->setRoutingGauge( getConfiguration()->getRoutingGauge() ); + _knik->setAllowedDepth( getConfiguration()->getAllowedDepth() ); _knik->createRoutingGraph(); - KnikEngine::setEdgeCapacityPercent( getEdgeCapacityPercent() ); + KnikEngine::setHEdgeCapacityPercent( getHEdgeCapacityPercent() ); + KnikEngine::setVEdgeCapacityPercent( getVEdgeCapacityPercent() ); // Decrease the edge's capacity only under the core area. const ChipTools& chipTools = getChipTools(); - float corePercent = getEdgeCapacityPercent(); + float corePercent = 1.00; float coronaPercent = 0.80; forEach ( Knik::Vertex*, ivertex, _knik->getRoutingGraph()->getVertexes() ) { for ( int i=0 ; i<2 ; ++i ) { Knik::Edge* edge = NULL; - bool isVEdge = false; if (i==0) { edge = ivertex->getHEdgeOut(); if (not edge) continue; - if (chipTools.intersectHPads(edge->getBoundingBox())) { + if (chipTools.hPadsEnclosed(edge->getBoundingBox())) { edge->setCapacity( 0 ); continue; } - isVEdge = false; + corePercent = getHEdgeCapacityPercent(); } else { edge = ivertex->getVEdgeOut(); if (not edge) continue; - if (chipTools.intersectVPads(edge->getBoundingBox())) { + if (chipTools.vPadsEnclosed(edge->getBoundingBox())) { edge->setCapacity( 0 ); continue; } - isVEdge = true; + corePercent = getVEdgeCapacityPercent(); } float edgePercent = 1.00; @@ -287,11 +296,12 @@ namespace Kite { edgePercent = corePercent; } else if (chipTools.getCorona().getOuterBox().contains(edge->getBoundingBox())) { edgePercent = coronaPercent; - isVEdge = false; } - unsigned int capacity = (unsigned int)(edge->getCapacity() * edgePercent ) - ((isVEdge) ? 1 : 0); - edge->setCapacity( capacity ); + float capacity = edgePercent * (float)edge->getCapacity(); + //cerr << "Appling capacity percentage " << (edgePercent*100.0) << "% (" + // << capacity << ") on: " << edge << endl; + edge->setCapacity( (unsigned int)capacity ); } } } @@ -333,7 +343,8 @@ namespace Kite { int vEdgeCapacity = 0; for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) { RoutingPlane* rp = _routingPlanes[depth]; - if (rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; + if (rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; + if (rp->getLayerGauge()->getDepth() > getConfiguration()->getAllowedDepth() ) continue; if (rp->getDirection() == KbHorizontal) ++hEdgeCapacity; else ++vEdgeCapacity; @@ -342,6 +353,7 @@ namespace Kite { for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) { RoutingPlane* rp = _routingPlanes[depth]; if (rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; + if (rp->getLayerGauge()->getDepth() > getConfiguration()->getAllowedDepth() ) continue; size_t tracksSize = rp->getTracksSize(); for ( size_t itrack=0 ; itrack (R3000,pipeline+chip). + // Test signals from (R3000,pipeline+chip). //DebugSession::addToTrace( getCell(), "mips_r3000_core.mips_r3000_1m_dp.banc.reada0" ); //DebugSession::addToTrace( getCell(), "mips_r3000_core.mips_r3000_1m_ct.i_ri(29)" ); //DebugSession::addToTrace( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_re(4)" ); @@ -503,6 +515,8 @@ namespace Kite { //DebugSession::addToTrace( getCell(), "dout_e_i(2)" ); //DebugSession::addToTrace( getCell(), "i_ack_i" ); //DebugSession::addToTrace( getCell(), "mips_r3000_core.mips_r3000_1m_dp.data_rm(7)" ); + // Test signals from . + //DebugSession::addToTrace( getCell(), "core.snx_inst.not_v_inc_out(9)" ); createDetailedGrid(); buildPowerRails(); @@ -528,7 +542,7 @@ namespace Kite { KatabaticEngine::loadGlobalRouting( method, nets ); Session::open( this ); - getGCellGrid()->checkEdgeSaturation( getEdgeCapacityPercent() ); + getGCellGrid()->checkEdgeSaturation( getHEdgeCapacityPercent() ); Session::close(); } @@ -560,7 +574,7 @@ namespace Kite { float edgeCapacity = 1.0; KnikEngine* knik = KnikEngine::get( getCell() ); - if (knik) edgeCapacity = knik->getEdgeCapacityPercent(); + if (knik) edgeCapacity = knik->getHEdgeCapacityPercent(); if (cparanoid.enabled()) { cparanoid << " o Post-checking Knik capacity overload " << (edgeCapacity*100.0) << "%." << endl; diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index 64929ff2..745caadf 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -390,11 +390,11 @@ namespace Kite { RoutingEvent* event = _eventQueue.pop(); if (tty::enabled()) { - cmess2 << " " << tty::cr; cmess2.flush (); } else { - cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " << event->getSegment() diff --git a/kite/src/PyGraphicKiteEngine.cpp b/kite/src/PyGraphicKiteEngine.cpp index 15f29db6..69b2a7b5 100644 --- a/kite/src/PyGraphicKiteEngine.cpp +++ b/kite/src/PyGraphicKiteEngine.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/kite/src/PyKiteEngine.cpp b/kite/src/PyKiteEngine.cpp index ef247664..56132742 100644 --- a/kite/src/PyKiteEngine.cpp +++ b/kite/src/PyKiteEngine.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2010-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2010-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -16,8 +15,11 @@ #include "hurricane/isobar/PyCell.h" +#include "hurricane/viewer/CellViewer.h" +#include "hurricane/viewer/ExceptionWidget.h" #include "hurricane/Cell.h" #include "kite/PyKiteEngine.h" +#include # undef ACCESS_OBJECT # undef ACCESS_CLASS @@ -36,6 +38,7 @@ namespace Kite { using Hurricane::in_trace; using Hurricane::Error; using Hurricane::Warning; + using Hurricane::ExceptionWidget; using Isobar::ProxyProperty; using Isobar::ProxyError; using Isobar::ConstructorError; @@ -53,6 +56,22 @@ extern "C" { #if defined(__PYTHON_MODULE__) +#define DirectVoidToolMethod(SELF_TYPE, SELF_OBJECT, FUNC_NAME) \ + static PyObject* Py##SELF_TYPE##_##FUNC_NAME(Py##SELF_TYPE* self) \ + { \ + trace << "Py" #SELF_TYPE "_" #FUNC_NAME "()" << endl; \ + HTRY \ + METHOD_HEAD(#SELF_TYPE "." #FUNC_NAME "()") \ + if (SELF_OBJECT->getViewer()) { \ + ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::FUNC_NAME,SELF_OBJECT) ); \ + } else { \ + SELF_OBJECT->FUNC_NAME(); \ + } \ + HCATCH \ + Py_RETURN_NONE; \ + } + + // +=================================================================+ // | "PyKiteEngine" Python Module Code Part | // +=================================================================+ @@ -109,7 +128,11 @@ extern "C" { METHOD_HEAD("KiteEngine.runGlobalRouter()") unsigned int flags = 0; if (PyArg_ParseTuple(args,"I:KiteEngine.runGlobalRouter", &flags)) { - kite->runGlobalRouter(flags); + if (kite->getViewer()) { + ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runGlobalRouter,kite,flags) ); + } else { + kite->runGlobalRouter(flags); + } } else { PyErr_SetString(ConstructorError, "KiteEngine.runGlobalRouter(): Invalid number/bad type of parameter."); return NULL; @@ -153,7 +176,11 @@ extern "C" { Py_DECREF(iterator); } - kite->loadGlobalRouting(flags,*routingNets); + if (kite->getViewer()) { + ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::loadGlobalRouting,kite,flags,*routingNets) ); + } else { + kite->loadGlobalRouting(flags,*routingNets); + } } else { PyErr_SetString(ConstructorError, "KiteEngine.loadGlobalRouting(): Invalid number/bad type of parameter."); return NULL; @@ -172,7 +199,12 @@ extern "C" { METHOD_HEAD("KiteEngine.layerAssign()") unsigned int flags = 0; if (PyArg_ParseTuple(args,"I:KiteEngine.layerAssign", &flags)) { - kite->layerAssign(flags); + + if (kite->getViewer()) { + ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::layerAssign,kite,flags) ); + } else { + kite->layerAssign(flags); + } } else { PyErr_SetString(ConstructorError, "KiteEngine.layerAssign(): Invalid number/bad type of parameter."); return NULL; @@ -183,11 +215,25 @@ extern "C" { } + static PyObject* PyKiteEngine_runNegociate ( PyKiteEngine* self ) + { + trace << "PyKiteEngine_runNegociate()" << endl; + HTRY + METHOD_HEAD("KiteEngine.runNegociate()") + if (kite->getViewer()) { + ExceptionWidget::catchAllWrapper( std::bind(&KiteEngine::runNegociate,kite,0) ); + } else { + kite->runNegociate(); + } + HCATCH + Py_RETURN_NONE; + } + + // Standart Accessors (Attributes). - DirectVoidMethod(KiteEngine,kite,runNegociate) - DirectVoidMethod(KiteEngine,kite,printConfiguration) - DirectVoidMethod(KiteEngine,kite,saveGlobalSolution) - DirectVoidMethod(KiteEngine,kite,finalizeLayout) + DirectVoidToolMethod(KiteEngine,kite,printConfiguration) + DirectVoidToolMethod(KiteEngine,kite,saveGlobalSolution) + DirectVoidToolMethod(KiteEngine,kite,finalizeLayout) DirectVoidMethod(KiteEngine,kite,dumpMeasures) DirectGetBoolAttribute(PyKiteEngine_getToolSuccess,getToolSuccess,PyKiteEngine,KiteEngine) diff --git a/kite/src/TrackElement.cpp b/kite/src/TrackElement.cpp index d16d5097..def2196a 100644 --- a/kite/src/TrackElement.cpp +++ b/kite/src/TrackElement.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/kite/src/kite/Configuration.h b/kite/src/kite/Configuration.h index f71f09e6..e4997406 100644 --- a/kite/src/kite/Configuration.h +++ b/kite/src/kite/Configuration.h @@ -17,7 +17,7 @@ #ifndef KITE_CONFIGURATION_H #define KITE_CONFIGURATION_H -#include +#include #include "katabatic/Configuration.h" @@ -39,66 +39,73 @@ namespace Kite { class Configuration : public Katabatic::Configuration { public: - typedef boost::function< void(void) > PostEventCb_t; + typedef std::function< void(void) > PostEventCb_t; public: - enum RipupTable { BorderRipupLimit =0 - , StrapRipupLimit =1 - , LocalRipupLimit =2 - , GlobalRipupLimit =3 - , LongGlobalRipupLimit=4 - , RipupLimitsTableSize=5 + enum RipupTable { StrapRipupLimit =0 + , LocalRipupLimit =1 + , GlobalRipupLimit =2 + , LongGlobalRipupLimit=3 + , RipupLimitsTableSize=4 }; enum Constants { MaxMetalDepth=20 }; public: // Constructor & Destructor. - virtual Configuration* clone () const; - virtual Configuration* clone ( KiteEngine* kite ) const; - Configuration ( Katabatic::Configuration* ); - ~Configuration (); - // Decorateds. - virtual bool isGMetal ( const Layer* ) const; - virtual bool isGContact ( const Layer* ) const; - virtual size_t getDepth () const; - virtual size_t getAllowedDepth () const; - virtual size_t getLayerDepth ( const Layer* ) const; - virtual RoutingGauge* getRoutingGauge () const; - virtual RoutingLayerGauge* getLayerGauge ( size_t depth ) const; - virtual const Layer* getRoutingLayer ( size_t depth ) const; - virtual Layer* getContactLayer ( size_t depth ) const; - virtual DbU::Unit getExtensionCap () const; - virtual float getSaturateRatio () const; - virtual size_t getSaturateRp () const; - virtual DbU::Unit getGlobalThreshold () const; - virtual size_t getHEdgeCapacity () const; - virtual size_t getVEdgeCapacity () const; - virtual void setAllowedDepth ( size_t ); - virtual void setSaturateRatio ( float ); - virtual void setSaturateRp ( size_t ); - virtual void setGlobalThreshold ( DbU::Unit ); - virtual void print ( Cell* ) const; - // Methods. - inline Katabatic::Configuration* base (); - inline PostEventCb_t& getPostEventCb (); - inline unsigned long getEventsLimit () const; - inline float getExpandStep () const; - inline unsigned int getRipupCost () const; - unsigned int getRipupLimit ( unsigned int type ) const; - inline float getEdgeCapacityPercent () const; - inline void setEventsLimit ( unsigned long ); - inline void setExpandStep ( float ); - inline void setRipupCost ( unsigned int ); - void setRipupLimit ( unsigned int limit, unsigned int type ); - inline void setPostEventCb ( PostEventCb_t ); - void setEdgeCapacityPercent ( float ); - virtual Record* _getRecord () const; - virtual string _getString () const; - virtual string _getTypeName () const; + virtual Configuration* clone () const; + virtual Configuration* clone ( KiteEngine* kite ) const; + Configuration ( Katabatic::Configuration* ); + ~Configuration (); + // Decorateds. + virtual bool isGMetal ( const Layer* ) const; + virtual bool isGContact ( const Layer* ) const; + virtual size_t getDepth () const; + virtual size_t getAllowedDepth () const; + virtual size_t getLayerDepth ( const Layer* ) const; + virtual RoutingGauge* getRoutingGauge () const; + virtual RoutingLayerGauge* getLayerGauge ( size_t depth ) const; + virtual const Layer* getRoutingLayer ( size_t depth ) const; + virtual Layer* getContactLayer ( size_t depth ) const; + virtual DbU::Unit getPitch ( size_t depth, unsigned int flags ) const; + virtual DbU::Unit getOffset ( size_t depth ) const; + virtual DbU::Unit getWireWidth ( size_t depth ) const; + virtual unsigned int getDirection ( size_t depth ) const; + virtual DbU::Unit getPitch ( const Layer*, unsigned int flags ) const; + virtual DbU::Unit getOffset ( const Layer* ) const; + virtual DbU::Unit getWireWidth ( const Layer* ) const; + virtual unsigned int getDirection ( const Layer* ) const; + virtual DbU::Unit getExtensionCap () const; + virtual float getSaturateRatio () const; + virtual size_t getSaturateRp () const; + virtual DbU::Unit getGlobalThreshold () const; + virtual size_t getHEdgeCapacity () const; + virtual size_t getVEdgeCapacity () const; + virtual void setAllowedDepth ( size_t ); + virtual void setSaturateRatio ( float ); + virtual void setSaturateRp ( size_t ); + virtual void setGlobalThreshold ( DbU::Unit ); + virtual void print ( Cell* ) const; + // Methods. + inline Katabatic::Configuration* base (); + inline PostEventCb_t& getPostEventCb (); + inline unsigned long getEventsLimit () const; + inline unsigned int getRipupCost () const; + unsigned int getRipupLimit ( unsigned int type ) const; + inline float getHEdgeCapacityPercent () const; + inline float getVEdgeCapacityPercent () const; + inline void setEventsLimit ( unsigned long ); + inline void setRipupCost ( unsigned int ); + void setRipupLimit ( unsigned int limit, unsigned int type ); + inline void setPostEventCb ( PostEventCb_t ); + void setHEdgeCapacityPercent ( float ); + void setVEdgeCapacityPercent ( float ); + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; private: // Attributes. Katabatic::Configuration* _base; PostEventCb_t _postEventCb; - float _edgeCapacityPercent; - float _expandStep; + float _hEdgeCapacityPercent; + float _vEdgeCapacityPercent; unsigned int _ripupLimits [RipupLimitsTableSize]; unsigned int _ripupCost; unsigned long _eventsLimit; @@ -109,16 +116,15 @@ namespace Kite { // Inline Functions. - inline Katabatic::Configuration* Configuration::base () { return _base; } - inline Configuration::PostEventCb_t& Configuration::getPostEventCb () { return _postEventCb; } - inline unsigned long Configuration::getEventsLimit () const { return _eventsLimit; } - inline unsigned int Configuration::getRipupCost () const { return _ripupCost; } - inline float Configuration::getExpandStep () const { return _expandStep; } - inline float Configuration::getEdgeCapacityPercent () const { return _edgeCapacityPercent; } - inline void Configuration::setRipupCost ( unsigned int cost ) { _ripupCost = cost; } - inline void Configuration::setExpandStep ( float step ) { _expandStep = step; } - inline void Configuration::setPostEventCb ( PostEventCb_t cb ) { _postEventCb = cb; } - inline void Configuration::setEventsLimit ( unsigned long limit ) { _eventsLimit = limit; } + inline Katabatic::Configuration* Configuration::base () { return _base; } + inline Configuration::PostEventCb_t& Configuration::getPostEventCb () { return _postEventCb; } + inline unsigned long Configuration::getEventsLimit () const { return _eventsLimit; } + inline unsigned int Configuration::getRipupCost () const { return _ripupCost; } + inline float Configuration::getHEdgeCapacityPercent () const { return _hEdgeCapacityPercent; } + inline float Configuration::getVEdgeCapacityPercent () const { return _vEdgeCapacityPercent; } + inline void Configuration::setRipupCost ( unsigned int cost ) { _ripupCost = cost; } + inline void Configuration::setPostEventCb ( PostEventCb_t cb ) { _postEventCb = cb; } + inline void Configuration::setEventsLimit ( unsigned long limit ) { _eventsLimit = limit; } diff --git a/kite/src/kite/GraphicKiteEngine.h b/kite/src/kite/GraphicKiteEngine.h index ba38fb27..46a3977a 100644 --- a/kite/src/kite/GraphicKiteEngine.h +++ b/kite/src/kite/GraphicKiteEngine.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -19,6 +18,7 @@ #ifndef KITE_GRAPHIC_KITE_ENGINE_H #define KITE_GRAPHIC_KITE_ENGINE_H +#include #include namespace Hurricane { @@ -50,9 +50,12 @@ namespace Kite { class GraphicKiteEngine : public GraphicTool { Q_OBJECT; + public: + enum Flags { NoFlags=0x0000, CreateEngine=0x0001 }; + public: KiteEngine* createEngine (); - KiteEngine* getForFramework (); + KiteEngine* getForFramework ( unsigned int flags ); static void initKatabaticAc ( CellWidget* ); static void drawKatabaticAc ( CellWidget* , const Go* @@ -88,12 +91,19 @@ namespace Kite { static GraphicKiteEngine* _singleton; CellViewer* _viewer; protected: - GraphicKiteEngine (); - virtual ~GraphicKiteEngine (); + GraphicKiteEngine (); + virtual ~GraphicKiteEngine (); + void _loadGlobalSolution (); + void _saveGlobalSolution (); + void _globalRoute (); + void _loadGlobalRouting (); + void _balanceGlobalDensity (); + void _runNegociate (); + void _finalize (); + void _save (); }; } // Kite namespace. - #endif // KITE_GRAPHIC_KITE_ENGINE_H diff --git a/kite/src/kite/KiteEngine.h b/kite/src/kite/KiteEngine.h index e2814f83..a1a54b48 100644 --- a/kite/src/kite/KiteEngine.h +++ b/kite/src/kite/KiteEngine.h @@ -24,6 +24,7 @@ namespace Hurricane { class Layer; class Net; class Cell; + class CellViewer; } #include "crlcore/RoutingGauge.h" @@ -44,6 +45,7 @@ namespace Kite { using Hurricane::Layer; using Hurricane::Net; using Hurricane::Cell; + using Hurricane::CellViewer; using CRL::RoutingGauge; using Katabatic::KatabaticEngine; @@ -62,6 +64,7 @@ namespace Kite { static KiteEngine* create ( Cell* ); static KiteEngine* get ( const Cell* ); public: + inline CellViewer* getViewer () const; inline KatabaticEngine* base (); inline Configuration* getKiteConfiguration (); virtual Configuration* getConfiguration (); @@ -71,8 +74,8 @@ namespace Kite { inline unsigned int getRipupLimit ( unsigned int type ) const; unsigned int getRipupLimit ( const TrackElement* ) const; inline unsigned int getRipupCost () const; - inline float getExpandStep () const; - inline float getEdgeCapacityPercent () const; + inline float getHEdgeCapacityPercent () const; + inline float getVEdgeCapacityPercent () const; virtual const Name& getName () const; inline Configuration::PostEventCb_t& getPostEventCb (); @@ -85,13 +88,14 @@ namespace Kite { void printCompletion () const; void dumpMeasures ( std::ostream& ) const; void dumpMeasures () const; + inline void setViewer ( CellViewer* ); inline void setPostEventCb ( Configuration::PostEventCb_t ); inline void setEventLimit ( unsigned long ); inline void setMinimumWL ( double ); inline void setRipupLimit ( unsigned int type, unsigned int ); inline void setRipupCost ( unsigned int ); - inline void setExpandStep ( float ); - inline void setEdgeCapacityPercent ( float ); + inline void setHEdgeCapacityPercent ( float ); + inline void setVEdgeCapacityPercent ( float ); void buildPowerRails (); void protectRoutingPads (); void preProcess (); @@ -119,6 +123,7 @@ namespace Kite { // Attributes. static Name _toolName; protected: + CellViewer* _viewer; Knik::KnikEngine* _knik; Net* _blockageNet; Configuration* _configuration; @@ -140,27 +145,29 @@ namespace Kite { // Inline Functions. - inline KatabaticEngine* KiteEngine::base () { return static_cast(this); } - inline Configuration* KiteEngine::getKiteConfiguration () { return _configuration; } - inline Net* KiteEngine::getBlockageNet () { return _blockageNet; } - inline Configuration::PostEventCb_t& KiteEngine::getPostEventCb () { return _configuration->getPostEventCb(); } - inline bool KiteEngine::getToolSuccess () const { return _toolSuccess; } - inline unsigned long KiteEngine::getEventsLimit () const { return _configuration->getEventsLimit(); } - inline unsigned int KiteEngine::getRipupCost () const { return _configuration->getRipupCost(); } - inline float KiteEngine::getExpandStep () const { return _configuration->getExpandStep(); } - inline float KiteEngine::getEdgeCapacityPercent () const { return _configuration->getEdgeCapacityPercent(); } - inline unsigned int KiteEngine::getRipupLimit ( unsigned int type ) const { return _configuration->getRipupLimit(type); } - inline NegociateWindow* KiteEngine::getNegociateWindow () { return _negociateWindow; } - inline size_t KiteEngine::getRoutingPlanesSize () const { return _routingPlanes.size(); } - inline void KiteEngine::setEventLimit ( unsigned long limit ) { _configuration->setEventsLimit(limit); } - inline void KiteEngine::setRipupLimit ( unsigned int type, unsigned int limit ) { _configuration->setRipupLimit(limit,type); } - inline void KiteEngine::setRipupCost ( unsigned int cost ) { _configuration->setRipupCost(cost); } - inline void KiteEngine::setExpandStep ( float step ) { _configuration->setExpandStep(step); } - inline void KiteEngine::setEdgeCapacityPercent ( float percent ) { _configuration->setEdgeCapacityPercent(percent); } - inline void KiteEngine::setMinimumWL ( double minimum ) { _minimumWL = minimum; } - inline void KiteEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { _configuration->setPostEventCb(cb); } - inline void KiteEngine::printConfiguration () const { _configuration->print(getCell()); } - inline TrackElement* KiteEngine::_lookup ( AutoSegment* segment ) const { return segment->getObserver(); } + inline CellViewer* KiteEngine::getViewer () const { return _viewer; } + inline KatabaticEngine* KiteEngine::base () { return static_cast(this); } + inline Configuration* KiteEngine::getKiteConfiguration () { return _configuration; } + inline Net* KiteEngine::getBlockageNet () { return _blockageNet; } + inline Configuration::PostEventCb_t& KiteEngine::getPostEventCb () { return _configuration->getPostEventCb(); } + inline bool KiteEngine::getToolSuccess () const { return _toolSuccess; } + inline unsigned long KiteEngine::getEventsLimit () const { return _configuration->getEventsLimit(); } + inline unsigned int KiteEngine::getRipupCost () const { return _configuration->getRipupCost(); } + inline float KiteEngine::getHEdgeCapacityPercent () const { return _configuration->getHEdgeCapacityPercent(); } + inline float KiteEngine::getVEdgeCapacityPercent () const { return _configuration->getVEdgeCapacityPercent(); } + inline unsigned int KiteEngine::getRipupLimit ( unsigned int type ) const { return _configuration->getRipupLimit(type); } + inline NegociateWindow* KiteEngine::getNegociateWindow () { return _negociateWindow; } + inline size_t KiteEngine::getRoutingPlanesSize () const { return _routingPlanes.size(); } + inline void KiteEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } + inline void KiteEngine::setEventLimit ( unsigned long limit ) { _configuration->setEventsLimit(limit); } + inline void KiteEngine::setRipupLimit ( unsigned int type, unsigned int limit ) { _configuration->setRipupLimit(limit,type); } + inline void KiteEngine::setRipupCost ( unsigned int cost ) { _configuration->setRipupCost(cost); } + inline void KiteEngine::setHEdgeCapacityPercent ( float percent ) { _configuration->setHEdgeCapacityPercent(percent); } + inline void KiteEngine::setVEdgeCapacityPercent ( float percent ) { _configuration->setVEdgeCapacityPercent(percent); } + inline void KiteEngine::setMinimumWL ( double minimum ) { _minimumWL = minimum; } + inline void KiteEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { _configuration->setPostEventCb(cb); } + inline void KiteEngine::printConfiguration () const { _configuration->print(getCell()); } + inline TrackElement* KiteEngine::_lookup ( AutoSegment* segment ) const { return segment->getObserver(); } // Variables. diff --git a/kite/src/kite/TrackElement.h b/kite/src/kite/TrackElement.h index 900d6bca..9b47d9fc 100644 --- a/kite/src/kite/TrackElement.h +++ b/kite/src/kite/TrackElement.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/kite/src/kite/TrackSegment.h b/kite/src/kite/TrackSegment.h index 195e4e10..1b6679ce 100644 --- a/kite/src/kite/TrackSegment.h +++ b/kite/src/kite/TrackSegment.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/knik/src/Edge.cpp b/knik/src/Edge.cpp index 2028caf1..39851fb5 100644 --- a/knik/src/Edge.cpp +++ b/knik/src/Edge.cpp @@ -81,6 +81,13 @@ void Edge::_preDestroy() Inherit::_preDestroy(); } +void Edge::setCapacity ( unsigned int capacity ) +// ***************************************** +{ + _capacity = capacity; +//cerr << "Setting capacity to " << _capacity << " on " << this << endl; +} + void Edge::increaseCapacity ( int capacity ) // ***************************************** { @@ -93,6 +100,8 @@ void Edge::increaseCapacity ( int capacity ) // cerr << "Increase Edge Capacity " << _from->getPosition() // << " to " << _to->getPosition() << ":" << _capacity << endl; +//cerr << "Increasing capacity to " << _capacity << " on " << this << endl; + if ( _capacity == 0 ) ltrace(300) << Warning("%s has reached NULL capacity.",getString(this).c_str()) << endl; } @@ -363,10 +372,12 @@ string Edge::_getString() const // **************************** { return "<" + _TName ( "Edge" ) - + ":" + getString ( _connexID ) - + " " + getString ( _netStamp ) - + " " + getString ( _from ) - + " " + getString ( _to ) + ">"; + + " id:" + getString( _connexID ) + + " s:" + getString( _netStamp ) + + " " + getString( _realOccupancy ) + + "/" + getString( _capacity ) + + " " + getString( _from ) + + " " + getString( _to ) + ">"; } Record* Edge::_getRecord() const diff --git a/knik/src/Graph.cpp b/knik/src/Graph.cpp index 2fcb98e2..f8bfda09 100644 --- a/knik/src/Graph.cpp +++ b/knik/src/Graph.cpp @@ -1,8 +1,11 @@ +#include #include #include +#include "hurricane/DebugSession.h" #include "hurricane/Warning.h" +#include "hurricane/Error.h" #include "hurricane/Name.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" @@ -27,6 +30,7 @@ #include "knik/Edge.h" #include "knik/HEdge.h" #include "knik/VEdge.h" +#include "knik/KnikEngine.h" #include "knik/flute.h" @@ -39,6 +43,12 @@ namespace Knik { + using Hurricane::inltrace; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::tab; + using Hurricane::ForEachIterator; + int depthMaterialize; unsigned countDijkstra = 0; unsigned countMonotonic = 0; @@ -75,9 +85,10 @@ struct segmentStat { unsigned getSumOv() const { return sumOv; }; }; -Graph::Graph ( Cell* cell, RoutingGrid* routingGrid, bool benchMode, bool useSegments ) -// ********************************************************************************************** - : _cell ( cell ) +Graph::Graph ( KnikEngine* engine, RoutingGrid* routingGrid, bool benchMode, bool useSegments ) +// ******************************************************************************************** + : _cell ( engine->getCell() ) + , _engine ( engine ) , _benchMode ( benchMode ) , _useSegments ( useSegments ) , _slicingTree ( NULL ) @@ -108,10 +119,10 @@ Graph::Graph ( Cell* cell, RoutingGrid* routingGrid, bool benchMode, bool useSeg __ripupMode__ = false; } -Graph* Graph::create ( Cell* cell, RoutingGrid* routingGrid, bool benchMode, bool useSegments ) -// ****************************************************************************************************** +Graph* Graph::create ( KnikEngine* engine, RoutingGrid* routingGrid, bool benchMode, bool useSegments ) +// **************************************************************************************************** { - Graph* _graph = new Graph ( cell, routingGrid, benchMode, useSegments ); + Graph* _graph = new Graph ( engine, routingGrid, benchMode, useSegments ); _graph->_postCreate(); @@ -129,33 +140,33 @@ void Graph::_postCreate() // XXX On supprime tout ce qui concerne NIMBUS et on considère qu'il existe toujours une _routingGrid XXX if ( !_routingGrid ) { - #ifdef __USE_MATRIXVERTEX__ - _matrixVertex = MatrixVertex::create(this); - if( !_matrixVertex ) - throw Error ("Graph::_postCreate(): cannot create MatrixVertex"); - _lowerLeftVertex = _matrixVertex->createRegularMatrix (); - cmess2 << " - Initialization done (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 << " - Size from routingGrid : " << _routingGrid->getNbXTiles() << ", " << _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 << " - Initialization done." << endl; - #else - throw Error ("Graph::_postCreate(): cannot use another method than MatrixVertex"); - #endif +#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 } // #ifdef __USE_MATRIXVERTEX__ // _matrixVertex = MatrixVertex::create(this); @@ -227,7 +238,7 @@ void Graph::_postCreate() for ( unsigned i = 0 ; i < _all_vertexes.size() ; i++ ) { _all_vertexes[i]->sortEdges(); } - cmess2 << " - Tri des edges terminé" << endl; + cmess2 << " - Edge sorting completed." << endl; STuple::setSTuplePQEnd ( _stuplePriorityQueue.end() ); @@ -511,11 +522,11 @@ Vertex* Graph::createVertex ( Point position, DbU::Unit halfWidth, DbU::Unit hal capacity = _routingGrid->getHCapacity(); //cerr << "createHEdge capacity:" << capacity << " ecp:" << ecp << endl; } else { - vector rtLGauges = AllianceFramework::get()->getRoutingGauge()->getLayerGauges(); + vector rtLGauges = _engine->getRoutingGauge()->getLayerGauges(); for ( vector::iterator it = rtLGauges.begin() ; it != rtLGauges.end() ; it++ ) { RoutingLayerGauge* routingLayerGauge = (*it); - if (routingLayerGauge->getType() != Constant::Default) - continue; + if (routingLayerGauge->getType() != Constant::Default) continue; + if (routingLayerGauge->getDepth() > _engine->getAllowedDepth()) continue; if (routingLayerGauge->getDirection() != Constant::Horizontal) continue; @@ -551,8 +562,8 @@ void Graph::createVEdge ( Vertex* from, Vertex* to, float ecp ) vector rtLGauges = AllianceFramework::get()->getRoutingGauge()->getLayerGauges(); for ( vector::iterator it = rtLGauges.begin() ; it != rtLGauges.end() ; it++ ) { RoutingLayerGauge* routingLayerGauge = (*it); - if (routingLayerGauge->getType() != Constant::Default) - continue; + if (routingLayerGauge->getType() != Constant::Default) continue; + if (routingLayerGauge->getDepth() > _engine->getAllowedDepth()) continue; if (routingLayerGauge->getDirection() != Constant::Vertical) continue; @@ -764,15 +775,16 @@ void Graph::increaseVTuplePriority ( VTuple* vtuple, float distance ) } void Graph::printVTuplePriorityQueue() -// ********************************** +// *********************************** { - cmess2 << "*** printing VTuplePriorityQueue ***" << endl; - VTuplePQIter pqit = _vtuplePriorityQueue.begin(); - while ( pqit != _vtuplePriorityQueue.end() ) { - cmess2 << (*pqit)->getVertex() << " : " << (*pqit)->getDistance() << endl; - pqit++; - } - cmess2 << "***********************************" << endl; + 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() @@ -830,12 +842,12 @@ void Graph::popMaxFromSTuplePQ() void Graph::addToSTuplePQ ( STuple* stuple ) // ***************************************** { - assert ( stuple ); - STuple::CostProperty* costProperty = stuple->getCostProperty(); - assert ( costProperty ); - costProperty->setPQIter ( _stuplePriorityQueue.insert ( stuple ) ); - STuple::STuplePQIter pqit = costProperty->getPQIter(); - assert ( (*pqit) == stuple ); + 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 ) @@ -1086,213 +1098,188 @@ int Graph::initRouting ( Net* net ) void Graph::Dijkstra() // ******************* { - //checkEmptyPriorityQueue(); +//checkEmptyPriorityQueue(); - //CEditor* editor = getCEditor( _nimbus->getCell() ); - countDijkstra++; + countDijkstra++; - // 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 ); +// 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 copy_vertex = _vertexes_to_route; // This is no more useful +// create a copy of _vertexes_to_route vector fo method UpdateEstimateCongestion +//set copy_vertex = _vertexes_to_route; // This is no more useful - //#if defined ( __USE_DYNAMIC_PRECONGESTION__ ) - if ( !__ripupMode__ && (__precongestion__ == 2) ) - UpdateEstimateCongestion(); - //#endif +//#if defined ( __USE_DYNAMIC_PRECONGESTION__ ) + if ( !__ripupMode__ && (__precongestion__ == 2) ) + UpdateEstimateCongestion(); +//#endif - //debugging = (dynamic_cast(_working_net) != NULL); - //debugging = (_working_net->getName() == debugName ); - bool debugging = false; + 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, "
Dijkstra
initialized
"); - if (debugging) { - cerr << "Dijkstra for net " << _working_net << " : " << _netStamp << endl; - cerr << " central vertex : " << centralVertex << endl; - cerr << " _vertexes_to_route.size : " << _vertexes_to_route.size() << endl; - //Breakpoint::stop(1, "
Dijkstra
initialized
"); + while ( _vertexes_to_route.size() > 1 ) { + // Now, let's expanse the top of the queue + VertexList reachedVertexes; + float reachedDistance = (float)(HUGE); + + //checkGraphConsistency(); + if (ltracelevel() >= 600) { + ltrace(600) << "_vertexes_to_route:" << endl; + for ( auto iv : _vertexes_to_route ) + ltrace(600) << "| " << iv << endl; } - while ( _vertexes_to_route.size() > 1 ) { - // Now, let's expanse the top of the queue - VertexList reachedVertexes; - float reachedDistance = (float)(HUGE); + ltrace(600) << "Source component" << endl; + printVTuplePriorityQueue(); + //Breakpoint::stop(1, "
Dijkstra
source connexe component
"); - //checkGraphConsistency(); + Vertex* firstVertex = getMinFromPriorityQueue(); + assert( firstVertex ); + Vertex* currentVertex = firstVertex; + int firstVertexConnex = firstVertex->getConnexID(); - // DEBUG // - if ( debugging ) { - cerr << " _vertexes_to_route :" << endl; - VertexSetIter vsit = _vertexes_to_route.begin(); - while ( vsit != _vertexes_to_route.end() ) { - cerr << " " << (*vsit) << endl; - vsit++; - } + 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; } - if ( debugging ) { - cerr << " source component" << endl; - printVTuplePriorityQueue(); - cerr.flush(); - Breakpoint::stop(1, "
Dijkstra
source connexe component
"); + 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, "
Dijkstra
distance has been updated
"); } - //if ( debugging && (editor->getStopLevel() >= 1) ) { - // editor->Refresh(); - // string stopMessage = "Source connexe component."; - // editor->Stop(stopMessage); - //} - Vertex* firstVertex = getMinFromPriorityQueue(); - assert ( firstVertex ); - Vertex* currentVertex = firstVertex; - int firstVertexConnex = firstVertex->getConnexID(); - - while ( currentVertex && (currentVertex->getDistance() < reachedDistance) ) { - PopMinFromPriorityQueue(); - assert ( !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) && (currentVertexConnex != firstVertexConnex) ) { - reachedDistance = currentVertex->getDistance(); - reachedVertexes.clear(); - if (debugging ) { - cerr << " reachedVertexes : clear + push_back vertex found in priorityQueue: " << currentVertex << endl; - } - reachedVertexes.push_back ( currentVertex ); + 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; + } } - Edge* arrivalEdgeCurrentVertex = currentVertex->getPredecessor(); - for_each_edge ( edge, currentVertex->getAdjacentEdges() ) { - if ( (edge->getNetStamp() == _netStamp) && (edge->getConnexID() == firstVertexConnex) ) { - // already visited edge - // ok because to reach a connex component the algorithm first reach a vertex !! - continue; - } - edge->setConnexID(-1); // reinitialize connexID for edge (was done by CleanRoutingState) - //edge->setSplitter(NULL); - edge->setNetStamp(_netStamp); - - Vertex* oppositeVertex = edge->getOpposite ( currentVertex ); - assert ( oppositeVertex ); - if ( !_searchingArea.contains ( oppositeVertex->getPosition() ) ) - continue; - float newDistance = currentVertex->getDistance() + edge->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; - } - int oppositeConnex = oppositeVertex->getConnexID(); - float oppositeDistance = oppositeVertex->getDistance(); - if ( updateOppositeVertex || (newDistance + EPSILON < oppositeDistance) ) { - assert ( oppositeConnex != firstVertexConnex ); - oppositeVertex->setPredecessor ( edge ); - oppositeVertex->setDistance ( newDistance ); - oppositeVertex->setNetStamp ( _netStamp ); - if ( VTuple* oppositeVTuple = oppositeVertex->getVTuple() ) { - if (debugging) { - cerr << " increasing Priority for vertex : " << oppositeVertex - << " and corresponding vtuple : " << oppositeVTuple->_getString() << endl; - } - increaseVTuplePriority ( oppositeVTuple, newDistance ); // XXX 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 ); - if (debugging) - cerr << " Creating new vtuple for vertex: " << oppositeVertex << "," << newDistance - << " --> " << newOppositeVTuple->_getString() << endl; - addVTupleToPriorityQueue ( newOppositeVTuple ); - } - if ( debugging ) { - cerr << " distance has been updated : " << edge << endl; - //cerr << " current reachedDistance: " << reachedDistance << " for: " << (*(reachedVertexes.begin())) << endl; - cerr << " current reachedDistance: " << reachedDistance << endl; - printVTuplePriorityQueue(); - Breakpoint::stop(1, "
Dijkstra
distance has been updated
"); - } - //if ( debugging && (editor->getStopLevel() >= 2) ) { - // editor->Refresh(); - // string stopMessage = "distance has been updated: "; - // stopMessage += getString ( edge ); - // editor->Stop(stopMessage); - //} - } - if ( (oppositeConnex != -1) && (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(); - //if (debugging ) { - // cerr << " second, push_back : " << oppositeVertex << endl; - // cerr << " reachedVertexes : clear + push_back reached vertex with < distance " << oppositeVertex << endl; - //} - reachedVertexes.push_back ( oppositeVertex ); - } - else if ( newDistance == reachedDistance ) { - VertexListIter lvit = reachedVertexes.begin(); - bool foundVertex = false; - // 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 ... - while ( lvit != reachedVertexes.end() ) { - // the following test depends on the fact we authorize multiple representant (vertex) - // of the same connexe component in reachedVertexes list - //if ( (*lvit)->getConnexID() == oppositeConnex ) - if ( (*lvit) == oppositeVertex ) { - foundVertex = true; - break; - } - lvit++; - } - if ( !foundVertex ) { - //if (debugging ) { - // cerr << " reachedVertexes : clear + push_back reached vertex with == distance " << oppositeVertex << endl; - //} - reachedVertexes.push_back ( oppositeVertex ); - } - } - else { - // Nothing to do ? - } - } - end_for; + if (not foundVertex) { + reachedVertexes.push_back( oppositeVertex ); + ltrace(600) << "Re-init (== distance) reachedVertexes with " << oppositeVertex << endl; } - currentVertex = getMinFromPriorityQueue(); + } else { + // Nothing to do? + } } - assert ( !reachedVertexes.empty() ); - assert ( reachedDistance < (float)(HUGE) ); + } - //if(debugging) { - // cerr << " updating 2 connex components : " << (*(reachedVertexes.begin())) << " & " << firstVertex << endl; - // cerr.flush(); - // editor->Refresh(); - // editor->Stop("Dijkstra on 2 connex comopnents, gonna Update"); - //} - UpdateConnexComp ( reachedVertexes, firstVertex ); - //if(debugging) { - // editor->Refresh(); - // editor->Stop("Update done"); - //} + currentVertex = getMinFromPriorityQueue(); } - //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 ; + 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) ); + + 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() @@ -1546,10 +1533,11 @@ void Graph::UpdateEstimateCongestion ( bool create ) if ( _vertexes_to_route.size() < 2 ) return; if ( _vertexes_to_route.size() >= FLUTE_LIMIT ) { - if ( create ) - cerr << "[INFO] Graph::UpdateEstiateGongestion(): Net " << _working_net << " has more than " << getString(FLUTE_LIMIT) - << " vertexes and can not be handled by FLUTE." << endl; - return; + 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 flutetree ( createFluteTree() ); @@ -1986,25 +1974,29 @@ unsigned Graph::analyseRouting ( set& segmentsToUnroute ) } } } + unsigned nbDep = 0; unsigned nbTot = 0; float minimalCost = 0; float maximalCost = 0; for ( map::iterator it = segmentsMap.begin() ; it != segmentsMap.end() ; it++ ) { - 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++; - } + 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++; + } } + forEach ( Net*, net, _cell->getNets() ) { forEach ( Contact*, contact, net->getContacts() ) { const Layer* cLayer = contact->getLayer(); @@ -2036,24 +2028,36 @@ unsigned Graph::analyseRouting ( set& segmentsToUnroute ) // } // } //} - 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; + + 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() ) { - cmess1 << " - Nothing to reroute !" << endl; - cmess1 << " - Maximum segment cost : 0" << endl; + //cmess1 << " - Nothing to reroute !" << endl; + //cmess1 << " - Maximum segment cost : 0" << endl; } else { STuple* topSTuple = getMaxFromSTuplePQ(); float maxCost = topSTuple->getCost(); - cmess1 << " - Maximum segment cost : " << maxCost << endl; + //cmess1 << " - Maximum segment cost : " << maxCost << endl; float minCost = 0.20; if (_stuplePriorityQueue.size() <= 100) minCost = 0.0; diff --git a/knik/src/GraphicKnikEngine.cpp b/knik/src/GraphicKnikEngine.cpp index 1735336a..0ebd1ad4 100644 --- a/knik/src/GraphicKnikEngine.cpp +++ b/knik/src/GraphicKnikEngine.cpp @@ -1,31 +1,23 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | -// | K n i k - Global Router | +// | K n i k - G l o b a l R o u t e r | // | | // | Author : Jean-Paul Chaput | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./GraphicKnikEngine.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Module : "./GraphicKnikEngine.cpp" | +// +-----------------------------------------------------------------+ #include #include #include +#include #include #include #include @@ -184,11 +176,11 @@ namespace Knik { { Cell* cell = getCell (); - emit cellPreModificated(); + //emit cellPreModificated(); cell->flattenNets ( Cell::BuildRings ); - emit cellPostModificated(); + //emit cellPostModificated(); } @@ -197,11 +189,11 @@ namespace Knik { KnikEngine* knik = createEngine ( BuildSolution ); if ( !knik ) return; - emit cellPreModificated (); + //emit cellPreModificated (); knik->run (); - emit cellPostModificated (); + //emit cellPostModificated (); } @@ -210,11 +202,11 @@ namespace Knik { KnikEngine* knik = createEngine ( BuildSolution ); if ( !knik ) return; - emit cellPreModificated (); + //emit cellPreModificated (); knik->Route (); - emit cellPostModificated (); + //emit cellPostModificated (); } @@ -222,7 +214,7 @@ namespace Knik { { Cell* cell = getCell (); - emit cellPreModificated(); + //emit cellPreModificated(); bool done = false; KnikEngine* knik = KnikEngine::get ( cell ); @@ -230,7 +222,7 @@ namespace Knik { done = knik->analyseRouting(); } - emit cellPostModificated(); + //emit cellPostModificated(); return done; } @@ -239,12 +231,12 @@ namespace Knik { { Cell* cell = getCell (); - emit cellPreModificated(); + //emit cellPreModificated(); KnikEngine* knik = KnikEngine::get ( cell ); if ( knik ) knik->unrouteOvSegments(); - emit cellPostModificated(); + //emit cellPostModificated(); } @@ -252,12 +244,12 @@ namespace Knik { { Cell* cell = getCell (); - emit cellPreModificated(); + //emit cellPreModificated(); KnikEngine* knik = KnikEngine::get ( cell ); if ( knik ) knik->reroute(); - emit cellPostModificated(); + //emit cellPostModificated(); } @@ -265,12 +257,12 @@ namespace Knik { { Cell* cell = getCell (); - emit cellPreModificated(); + //emit cellPreModificated(); KnikEngine* knik = KnikEngine::get ( cell ); if ( knik ) knik->saveSolution(); - emit cellPostModificated(); + //emit cellPostModificated(); } @@ -279,11 +271,11 @@ namespace Knik { KnikEngine* knik = createEngine ( LoadSolution ); if ( !knik ) return; - emit cellPreModificated(); + //emit cellPreModificated(); knik->loadSolution(); - emit cellPostModificated(); + //emit cellPostModificated(); } @@ -413,9 +405,6 @@ namespace Knik { connect ( gLoadAction, SIGNAL(triggered()), this, SLOT(loadSolution()) ); } // fin du sous menu - - connect ( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) ); - connect ( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) ); } diff --git a/knik/src/KnikEngine.cpp b/knik/src/KnikEngine.cpp index 976f022b..c30bcdd0 100644 --- a/knik/src/KnikEngine.cpp +++ b/knik/src/KnikEngine.cpp @@ -1,53 +1,20 @@ +// -*- C++ -*- // -// This file is part of the Coriolis Project. -// Copyright (C) Laboratoire LIP6 - Departement ASIM -// Universite Pierre et Marie Curie +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2006-2014, All Rights Reserved // -// Main contributors : -// Christophe Alexandre -// Hugo Cl�ment -// Jean-Paul Chaput -// Christian Masson -// -// The Coriolis Project is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// The Coriolis Project is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with the Coriolis Project; if not, write to the Free Software -// Foundation, inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// -// License-Tag -// -// -// Date : 30/10/2006 -// Author : Damien Dupuis -// -// Authors-Tag -// -// x-----------------------------------------------------------------x -// | | +// x-----------------------------------------------------------------x // | C O R I O L I S | -// | Alliance / Hurricane Interface | +// | K n i k - G l o b a l R o u t e r | // | | -// | Author : Damien DUPUIS | -// | E-mail : Damien.Dupuis.lip6.fr | +// | Author : Damien Dupuis | +// | E-mail : Damien.Dupuis@lip6.fr | // | =============================================================== | -// | C++ Module : "./Knik.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | +// | C++ Header : "./KnikEngine.cpp" | // x-----------------------------------------------------------------x -#include +#include #include "hurricane/Warning.h" #include "hurricane/RoutingPad.h" #include "hurricane/Property.h" @@ -59,14 +26,12 @@ #include "hurricane/DataBase.h" #include "hurricane/UpdateSession.h" #include "hurricane/Breakpoint.h" - #include "crlcore/Utilities.h" #include "crlcore/ToolBox.h" #include "crlcore/Measures.h" #include "crlcore/RoutingGauge.h" #include "crlcore/RoutingLayerGauge.h" #include "crlcore/AllianceFramework.h" - #include "knik/Configuration.h" #include "knik/Edge.h" #include "knik/Vertex.h" @@ -76,9 +41,11 @@ #include "knik/KnikEngine.h" #include "knik/flute.h" + #define MAX_RUNTIME 86400 #define MAX_ITERATION UINT_MAX + namespace Knik { using Hurricane::Warning; @@ -88,40 +55,51 @@ namespace Knik { using CRL::AllianceFramework; -//globale variables -unsigned __congestion__; -unsigned __precongestion__; -float __edge_cost__; -bool __initialized__; +// Global Variables + unsigned int __congestion__; + unsigned int __precongestion__; + float __edge_cost__; + bool __initialized__; + + extern bool __ripupMode__; -extern bool __ripupMode__; + const Name KnikEngine::_toolName = "Knik::KnikEngine"; + float KnikEngine::_edgeHCapacityPercent = 1.0; + float KnikEngine::_edgeVCapacityPercent = 1.0; -const Name KnikEngine::_toolName = "Knik::KnikEngine"; -float KnikEngine::_edgeCapacityPercent = 1.0; -KnikEngine::KnikEngine ( Cell* cell, unsigned congestion, unsigned precongestion, bool benchMode, bool useSegments, float edgeCost ) -// ********************************************************************************************************************************* - : Inherit ( cell ) - , _routingGraph ( NULL ) - , _routingGrid ( NULL ) - , _benchMode ( benchMode ) - , _useSegments ( useSegments ) - , _routingDone ( false ) - , _rerouteIteration ( 0 ) + KnikEngine::KnikEngine ( Cell* cell + , unsigned congestion + , unsigned precongestion + , bool benchMode + , bool useSegments + , float edgeCost ) + : CRL::ToolEngine ( cell ) + , _routingGauge ( NULL ) + , _allowedDepth ( 0) + , _routingGraph ( NULL ) + , _routingGrid ( NULL ) + , _benchMode ( benchMode ) + , _useSegments ( useSegments ) + , _routingDone ( false ) + , _rerouteIteration( 0 ) , _segmentOverEdges() - , _sortSegmentOv() -{ - if ( congestion > 1 ) + , _sortSegmentOv () + { + if (congestion > 1) throw Error ( "KnikEngine::KnikEngine(): congestion argument must be 0 (None) or 1 (Congestion) : %s." , getString(congestion).c_str() ); __congestion__ = congestion; + if ( precongestion > 2 ) throw Error ( "KnikEngine::KnikEngine(): precongestion argument must be 0 (None), 1 (Static) or 2 (Dynamic) : %s." , getString(precongestion).c_str() ); + __precongestion__ = precongestion; - __edge_cost__ = edgeCost; - __initialized__ = false; -} + __edge_cost__ = edgeCost; + __initialized__ = false; + } + KnikEngine::~KnikEngine () // *********************** @@ -136,10 +114,11 @@ KnikEngine* KnikEngine::create ( Cell* cell, unsigned congestion, unsigned preco _knik->_postCreate(); - cout << " o Knik -- Global router makes use of FLUTE software" << endl; - cout << Dots::asIdentifier(" - Author" ,"Chris C. N. CHU") << endl; - cout << Dots::asIdentifier(" - Prof. Ident. ","Iowa State University") << endl; - cout << Dots::asIdentifier(" - URL" ,"http://home.eng.iastate.edu/~cnchu") << endl; + // This is also printed in the banner of Unicorn/Cgt, no need to remind it here again. + // cout << " o Knik -- Global router makes use of FLUTE software" << endl; + // cout << Dots::asIdentifier(" - Author" ,"Chris C. N. CHU") << endl; + // cout << Dots::asIdentifier(" - Prof. Ident. ","Iowa State University") << endl; + // cout << Dots::asIdentifier(" - URL" ,"http://home.eng.iastate.edu/~cnchu") << endl; return _knik; } @@ -171,6 +150,23 @@ void KnikEngine::_preDestroy() return; } + + void KnikEngine::setRoutingGauge ( RoutingGauge* rg ) + { + _routingGauge = rg; + _allowedDepth = rg->getDepth(); + } + + + void KnikEngine::setAllowedDepth ( unsigned int allowedDepth ) + { + if (not _routingGauge) + cerr << Error( "KnikEngine::setAllowedDepth(): Must set the RoutingGauge before the allowed depth." ) << endl; + + _allowedDepth = (allowedDepth < _routingGauge->getDepth()) ? allowedDepth : _routingGauge->getDepth(); + } + + void KnikEngine::MakeRoutingLeaves() // ********************************* { @@ -196,97 +192,77 @@ void KnikEngine::MakeRoutingLeaves() void KnikEngine::initGlobalRouting() // ********************************* { - assert ( _nets_to_route.empty() ); - cmess2 << " o Knik::initGlobalRouting()" << endl; - //#if defined(__USE_STATIC_PRECONGESTION__) || defined(__USE_DYNAMIC_PRECONGESTION__) - cmess2 << " - Congestion: " << __congestion__ << endl; - cmess2 << " - PreCongestion: " << __precongestion__ << endl; - cmess2 << " - EdgeCost: " << __edge_cost__ << endl; - //#endif - - // create the route graph - if ( !_routingGraph ) { - _timer.resetIncrease(); - _timer.start(); - cmess2 << " o CLOSE sessionCreate routing graph." << endl; - Cell* cell = getCell(); - _routingGraph = Graph::create ( cell, _routingGrid, _benchMode, _useSegments ); - cmess2 << " - Graph size: " << _routingGraph->getXSize() - << "x" << _routingGraph->getYSize() << endl; - _timer.stop(); - printTime(); - } - else { - cmess2 << " - Reusing pre-existing graph." << endl; - } - - // 20/02/09 tout ce qui suit dans la fonction etait inclu dans le if(!_routingGraph) on le sépare pour pouvoir - // créer explicitement le graph dans une fonction, pour + assert( _nets_to_route.empty() ); + cmess2 << " o Initializing global routing." << endl; +//#if defined(__USE_STATIC_PRECONGESTION__) || defined(__USE_DYNAMIC_PRECONGESTION__) + cmess1 << Dots::asUInt ( " - Congestion Mode" , __congestion__ ) << endl; + cmess1 << Dots::asUInt ( " - Pre-Congestion Mode", __precongestion__ ) << endl; + cmess1 << Dots::asDouble( " - Edge Cost" , __edge_cost__ ) << endl; +//#endif + if (not _routingGraph) { _timer.resetIncrease(); _timer.start(); - cmess2 << " o Selecting nets to route and create precongestion" << endl; - const unsigned int MaxDegree = 13000; - Name obstacleNetName ("obstaclenet"); - - //for_each_occurrence ( occurrence, cell->getHyperNetRootNetOccurrences() ) // working on deepNets - for_each_net ( net, getCell()->getNets() ) { - //Net* net = dynamic_cast(occurrence.getEntity()); // working on deepNets - - assert(net); - - //cerr << " Net : " << net << endl; - if ( net->isGlobal() - or net->isSupply() - or net->isClock() - or (net->getName() == obstacleNetName) ) { - cmess1 << " - <" << net->getName() << "> not routed (global, supply, clock or obstacle)." << endl; - continue; - } - - //if ( !isVeryFlatCell && net->getCell()->isLeaf() ) { // Don't want to route Leaf Cells nets - // //cerr << " rootNet belongs to a leaf cell => continue" << endl; - // continue; - //} // working on deepNets - - // We want to route nets with more at least 2 and less than MaxDegree vertexes - unsigned netDegree = _routingGraph->countVertexes ( net ); - if ( netDegree > 1 && netDegree < MaxDegree ) { - Box bbox = net->getBoundingBox(); - NetRecord record ( net, (long int)((DbU::getLambda(bbox.getWidth())+1)*(DbU::getLambda(bbox.getHeight())+1)) ); - assert ( record._net ); - assert ( record._exArea > 0 ); - _nets_to_route.push_back ( record ); - //#if defined(__USE_STATIC_PRECONGESTION__) || defined(__USE_DYNAMIC_PRECONGESTION__) - if ( __precongestion__ ) - _routingGraph->UpdateEstimateCongestion ( true ); - //#endif - //cerr << " will be routed." << endl; - } - else { - if ( netDegree > MaxDegree-1 ) - cmess1 << Warning("%s has a not a degree in [2:%u[ (%d), not routed." - ,getString(net).c_str(),MaxDegree,netDegree) << endl; - } - - _routingGraph->resetVertexes(); - end_for; - } - stable_sort ( _nets_to_route.begin(), _nets_to_route.end(), NetSurfacesComp() ); - NetVector::iterator new_end = unique ( _nets_to_route.begin(), _nets_to_route.end() ); - _nets_to_route.erase ( new_end, _nets_to_route.end() ); + _routingGraph = Graph::create ( this, _routingGrid, _benchMode, _useSegments ); + cmess2 << " - Created RoutingGraph [" << _routingGraph->getXSize() + << "x" << _routingGraph->getYSize() << "]." << endl; _timer.stop(); - printTime(); - cmess2 << " + Nets to route: " << _nets_to_route.size() << endl; - //#endif + } else { + cmess2 << " - Reusing pre-existing graph." << endl; + } - // 20/02/09 fin de l'ancienne inclusion + _timer.resetIncrease(); + _timer.start(); - __initialized__ = true; + cmess2 << " o Selecting nets to route and create precongestion." << endl; + + const unsigned int MaxDegree = 13000; + Name obstacleNetName ("obstaclenet"); + + forEach ( Net*, inet, getCell()->getNets() ) { + if ( inet->isGlobal() + or inet->isSupply() + or inet->isClock() + or (inet->getName() == obstacleNetName) ) { + cmess2 << " - <" << inet->getName() << "> not routed (global, supply, clock or obstacle)." << endl; + continue; + } + + // We want to route nets with more at least 2 and less than MaxDegree vertexes + unsigned netDegree = _routingGraph->countVertexes ( *inet ); + if ( (netDegree > 1) and (netDegree < MaxDegree) ) { + Box bbox = inet->getBoundingBox(); + NetRecord record ( *inet, (long int)((DbU::getLambda(bbox.getWidth())+1)*(DbU::getLambda(bbox.getHeight())+1)) ); + assert( record._net ); + assert( record._exArea > 0 ); + + _nets_to_route.push_back( record ); +//#if defined(__USE_STATIC_PRECONGESTION__) || defined(__USE_DYNAMIC_PRECONGESTION__) + if (__precongestion__) + _routingGraph->UpdateEstimateCongestion( true ); +//#endif + } else { + if (netDegree > MaxDegree-1) + cmess1 << Warning("%s has a not a degree in [2:%u[ (%d), not routed." + ,getString(*inet).c_str(),MaxDegree,netDegree) << endl; + } + + _routingGraph->resetVertexes(); + } + + stable_sort( _nets_to_route.begin(), _nets_to_route.end(), NetSurfacesComp() ); + NetVector::iterator new_end = unique( _nets_to_route.begin(), _nets_to_route.end() ); + _nets_to_route.erase( new_end, _nets_to_route.end() ); + + _timer.stop(); + cmess2 << " - # of Nets to route:" << _nets_to_route.size() << endl; + + __initialized__ = true; } + void KnikEngine::createRoutingGrid ( unsigned nbXTiles , unsigned nbYTiles , const Box& boundingBox @@ -308,8 +284,7 @@ void KnikEngine::createRoutingGrid ( unsigned nbXTiles void KnikEngine::createRoutingGraph() // ********************************** { - Cell* cell = getCell(); - _routingGraph = Graph::create ( cell, _routingGrid, _benchMode, _useSegments ); + _routingGraph = Graph::create ( this, _routingGrid, _benchMode, _useSegments ); //Breakpoint::stop ( 0, "Point d'arret:
  createGlobalGraph() " // "after Knik createGlobalGraph()." ); @@ -608,7 +583,7 @@ string KnikEngine::adaptString ( string s ) void KnikEngine::unrouteOvSegments() // ********************************* { - cmess2 << " o Unroute overflowed segments :" << endl; + //cmess2 << " o Unroute overflowed segments :" << endl; unsigned countSegments = 0; unsigned countContacts = 0; UpdateSession::open(); @@ -768,12 +743,15 @@ void KnikEngine::unrouteOvSegments() } while ( !_segmentsToUnroute.empty() ); _timer.suspend(); - cmess2 << " + Done in " << _timer.getCombTime() - << "s [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl; + //cmess2 << " + Done in " << _timer.getCombTime() + // << "s [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl; UpdateSession::close(); - cmess2 << " - Segments destroyed : " << countSegments << endl - << " - Contacts destroyed : " << countContacts << endl; + //cmess2 << " - Segments destroyed : " << countSegments << endl + // << " - Contacts destroyed : " << countContacts << endl; + + cmess2 << " Destroyed. Segments: " << countSegments + << " Contacts:" << countContacts << endl; } @@ -870,7 +848,7 @@ void KnikEngine::unroute ( Segment* segment, set &segmentsToUnroute, C void KnikEngine::computeOverflow() // ******************************* { - cmess1 << " o Computing Statistics" << endl; + //cmess1 << " o Computing Statistics" << endl; Vertex* currentVertex = _routingGraph->getLowerLeftVertex(); int nbEdgesTotal = 0; int nbEdgesOver = 0; @@ -945,7 +923,7 @@ void KnikEngine::computeOverflow() else break; } - cmess2 << " - first skimming through edges done (overflow computed)" << endl; + //cmess2 << " - first skimming through edges done (overflow computed)" << endl; //averageOver = nbEdgesOver == 0 ? 0 : averageOver / (float)nbEdgesOver; // Now we've got the max we can print more detailed statistics about edges overflow @@ -985,7 +963,7 @@ void KnikEngine::computeOverflow() else break; } - cmess2 << " - second skimming through edges done (overflow details)" << endl; + //cmess2 << " - second skimming through edges done (overflow details)" << endl; } unsigned _wirelength = 0; @@ -1013,7 +991,7 @@ void KnikEngine::computeOverflow() } NetExtension::setWireLength ( *net, netWirelength ); } - cmess2 << " - Wirelength computed" << endl; + //cmess2 << " - Wirelength computed" << endl; // *** Cannot build column several times, no hasColumn function *** // CEditor* editor = getCEditor ( getCell() ); // CNetListWindow* netListWindow = editor->getNetListWindow(); @@ -1023,18 +1001,18 @@ void KnikEngine::computeOverflow() // } // cmess2 << " - Netlist window rebuild" << endl; // cmess1 << " - Total number of edges : " << nbEdgesTotal << endl - cmess1 << " - Number of overcapacity edges : " << nbEdgesOver << " / " << nbEdgesTotal << 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 - << " - # of overflow : " << overflow << endl - << " - max of overflow : " << maxOver << endl; -// << " - # of net with overflow : " << _netNbOverEdges.size() << endl - cmess1 << " - grid wirelength : " << _gridWirelength << endl; - cmess2 << " - grid wirelength : " << _gridWirelength << endl - << " - grid wirelength w/o via : " << _gridWirelengthWoVia << endl - << " - real wirelength : " << _wirelength << endl; +// cmess1 << " - Number of overcapacity edges : " << nbEdgesOver << " / " << nbEdgesTotal << 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 +// << " - # of overflow : " << overflow << endl +// << " - max of overflow : " << maxOver << endl; +// // << " - # of net with overflow : " << _netNbOverEdges.size() << endl +// cmess1 << " - grid wirelength : " << _gridWirelength << endl; +// cmess2 << " - grid wirelength : " << _gridWirelength << endl +// << " - grid wirelength w/o via : " << _gridWirelengthWoVia << endl +// << " - real wirelength : " << _wirelength << endl; //if ( ! ovEdgesStats.empty() ) { // // print details about edges overflow @@ -1068,6 +1046,13 @@ void KnikEngine::run() done = analyseRouting(); } + ostringstream result; + + result << Timer::getStringTime(_timer.getCombTime()) + << ", " << Timer::getStringMemory(_timer.getIncrease()); + cmess1 << " o Global Routing Completed." << endl; + cmess1 << Dots::asString( " - Done in", result.str() ) << endl; + addMeasure ( getCell(), "knikT", _timer.getCombTime () ); addMeasure ( getCell(), "knikS", (_timer.getMemorySize() >> 20) ); @@ -1084,7 +1069,9 @@ void KnikEngine::Route() _timer.resetIncrease(); _timer.start(); - cmess1 << " o Knik::Route()" << endl; + cmess1 << " o Global Routing." << endl; + cmess2 << " Iteration INIT" + << " # of nets to route:" << left << _nets_to_route.size() << endl; //CEditor* editor = getCEditor ( getCell() ); //editor->showRubbers(); @@ -1123,26 +1110,19 @@ void KnikEngine::Route() //cmess1 << "%]\r"; } _timer.suspend(); - cmess1 << " - [100%]: " << size << " nets routed." << endl; - //cmess2 << " - NbSplitters : " << _routingGraph->getNbSplitters() << endl; - cmess2 << " + Done in " << _timer.getCombTime() - << "s [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl; - cmess2 << " (raw measurements : " << _timer.getCombTime() - << "s [+" << (_timer.getIncrease()>>10) << "Ko/" - << (_timer.getMemorySize()>>10) << "Ko])" << endl; + cmess2 << " Elapsed time: " << _timer.getCombTime() + << " Memory: " << Timer::getStringMemory(_timer.getIncrease()) << endl; // Comment to test with transhierarchic MIPS //computeOverflow(); - // To be able to plot congestionMap, we need to UpdateMaxEstimateCongestion : //_routingGraph->UpdateMaxEstimateCongestion(); // no more useful since qe use QT which allow to see colored edges. // passage en mode PERFORMANCE ! //_routingGraph->testSTuplePQ(); - // While not debugging, comment this out : //_routingGraph->destroy(); UpdateSession::close(); @@ -1162,13 +1142,13 @@ bool KnikEngine::analyseRouting() } unsigned overflow = _routingGraph->analyseRouting (_segmentsToUnroute); - cmess2 << " - Segments to unroute : " << _segmentsToUnroute.size() << endl; + //cmess2 << " - Segments to unroute : " << _segmentsToUnroute.size() << endl; // redefine the new _nets_to_route vector _nets_to_route.clear(); for ( set::iterator it = _segmentsToUnroute.begin() ; it != _segmentsToUnroute.end() ; it++ ) { - cmess2 << " "<< (*it) << endl; + //cmess2 << " "<< (*it) << endl; Net* net = (*it)->getNet(); bool present = false; @@ -1198,8 +1178,8 @@ bool KnikEngine::analyseRouting() //cmess1 << endl; _timer.suspend(); - cmess1 << " + Done in " << _timer.getCombTime() - << "s [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl; + // cmess1 << " + Done in " << _timer.getCombTime() + // << "s [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl; bool done = false; if ( (overflow==0) || (_timer.getCombTime() >= MAX_RUNTIME) || (_rerouteIteration >= MAX_ITERATION) ) @@ -1212,44 +1192,47 @@ void KnikEngine::reroute() { UpdateSession::open(); - //Breakpoint::setStopLevel(1); - //analyseRouting(); - //unrouteOvSegments(); - cmess1 << " o Knik::reroute() : iteration " << ++_rerouteIteration << endl; + //Breakpoint::setStopLevel(1); + //analyseRouting(); + //unrouteOvSegments(); + + cmess2 << " Iteration " << right << setw(4) << setfill('0') << ++_rerouteIteration + << " # of nets to route:" << left << _nets_to_route.size() << endl; + _timer.resume(); - unsigned size = _nets_to_route.size(); + unsigned int size = _nets_to_route.size(); __ripupMode__ = true; - for ( unsigned i = 0 ; i < size ; i++ ) { - Net* net = _nets_to_route[i]._net; - assert ( net ); - //_routingGraph->checkGraphConsistency(); - switch ( _routingGraph->initRouting ( net ) ) { - case 0: - case 1: - //cerr << "Nothing to global route" << endl; - break; - default: - _routingGraph->Dijkstra(); - break; - } - - _routingGraph->incNetStamp(); - _routingGraph->CleanRoutingState(); - //cmess1 << " - ["; - //cmess1.width(3); - //cmess1 << floor((float)(i*100)/(float)(size)); - //cmess1 << "%]\r"; - } - _timer.suspend(); - cmess1 << " - [100%]: " << size << " nets routed." << endl; - //cmess2 << " - NbSplitters : " << _routingGraph->getNbSplitters() << endl; - cmess2 << " + Done in " << _timer.getCombTime() - << " [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl; - cmess2 << " (raw measurements : " << _timer.getCombTime() - << "s [+" << (_timer.getIncrease()>>10) << "Ko/" - << (_timer.getMemorySize()>>10) << "Ko])" << endl; + for ( unsigned i = 0 ; i < size ; ++i ) { + Net* net = _nets_to_route[i]._net; + assert( net ); + //_routingGraph->checkGraphConsistency(); + + switch ( _routingGraph->initRouting(net) ) { + case 0: + case 1: + //cerr << "Nothing to global route" << endl; + break; + default: + _routingGraph->Dijkstra(); + break; + } + + _routingGraph->incNetStamp(); + _routingGraph->CleanRoutingState(); + } + + _timer.suspend(); + + cmess2 << " Elapsed time: " << _timer.getCombTime() + << " Memory: " << Timer::getStringMemory(_timer.getIncrease()) << endl; + + // cmess2 << " + Done in " << _timer.getCombTime() + // << " [+" << Timer::getStringMemory(_timer.getIncrease()) << "]." << endl; + // cmess2 << " (raw measurements : " << _timer.getCombTime() + // << "s [+" << (_timer.getIncrease()>>10) << "Ko/" + // << (_timer.getMemorySize()>>10) << "Ko])" << endl; // Comment to test with transhierarchic MIPS //computeOverflow(); @@ -1263,28 +1246,29 @@ void KnikEngine::reroute() void KnikEngine::computeSymbolicWireLength () { -// Ugly: hardcoded SxLib gauge characteristics. + if (not _routingGauge) + throw Error( "KnikEngine::computeSymbolicWireLength(): The routing gauge has not been set." ); - size_t hEdgeCapacity = 0; - size_t vEdgeCapacity = 0; - double gcellSide = 50.0; + size_t hEdgeCapacity = 0; + size_t vEdgeCapacity = 0; + DbU::Unit gcellSide = DbU::fromLambda( 50.0 ); - RoutingGauge* rg = AllianceFramework::get()->getRoutingGauge(); - vector::const_iterator ilayerGauge = rg->getLayerGauges().begin(); - for ( ; ilayerGauge != rg->getLayerGauges().end() ; ++ilayerGauge ) { + vector::const_iterator ilayerGauge = _routingGauge->getLayerGauges().begin(); + for ( ; ilayerGauge != _routingGauge->getLayerGauges().end() ; ++ilayerGauge ) { RoutingLayerGauge* layerGauge = (*ilayerGauge); - if ( layerGauge->getType() != Constant::Default ) continue; + if (layerGauge->getType() != Constant::Default) continue; + if (layerGauge->getDepth() > _allowedDepth) continue; - if ( layerGauge->getDirection() == Constant::Horizontal ) { - hEdgeCapacity += layerGauge->getTrackNumber ( 0, DbU::lambda(50.0) ) - 1; + if (layerGauge->getDirection() == Constant::Horizontal) { + hEdgeCapacity += layerGauge->getTrackNumber( 0, gcellSide ) - 1; } else if ( layerGauge->getDirection() == Constant::Vertical ) { - vEdgeCapacity += layerGauge->getTrackNumber ( 0, DbU::lambda(50.0) ) - 1; + vEdgeCapacity += layerGauge->getTrackNumber( 0, gcellSide ) - 1; } } // Complete formula: unitarian Wirelength/Area for one GCell. // (side*(hEdgeCapacity+vEdgeCapacity)) / (side * side). - const double normalize = ((double)(hEdgeCapacity+vEdgeCapacity)) / gcellSide; + const double normalize = ((double)(hEdgeCapacity+vEdgeCapacity)) / DbU::toLambda(gcellSide); unsigned long long symbolicWireLength = 0; forEach ( Net*, net, getCell()->getNets() ) { diff --git a/knik/src/MatrixVertex.cpp b/knik/src/MatrixVertex.cpp index cda27293..b84706ee 100644 --- a/knik/src/MatrixVertex.cpp +++ b/knik/src/MatrixVertex.cpp @@ -171,7 +171,8 @@ Vertex* MatrixVertex::createRegularMatrix () // << " - latestTileHeight : " << _latestTileHeight << endl; // On cree les vecteurs de vertex en meme temps que les vertex et aussi les edges ! - float ecp = KnikEngine::get ( cell )->getEdgeCapacityPercent(); + float hecp = KnikEngine::get( cell )->getHEdgeCapacityPercent(); + float vecp = KnikEngine::get( cell )->getVEdgeCapacityPercent(); for ( unsigned j = 0 ; j < _nbYTiles ; j++ ) { vector vect; for ( unsigned i = 0 ; i < _nbXTiles ; i++ ) { @@ -190,7 +191,7 @@ Vertex* MatrixVertex::createRegularMatrix () assert(from); Vertex* to = vect[i]; assert(to); - _routingGraph->createHEdge ( from, to, ecp ); + _routingGraph->createHEdge ( from, to, hecp ); } // si j > 0 alors on peut creer une edge verticale entre matrix[i][j-1] et matrix[i][j] c'est a dire _matrix[j-1][i] et vect[i] if ( j > 0 ) { // _matrix est un vecteur de vecteur represantant les lignes -> _matrix[ligne][colonne] @@ -198,7 +199,7 @@ Vertex* MatrixVertex::createRegularMatrix () assert(from); Vertex* to = vect[i]; assert(to); - _routingGraph->createVEdge ( from, to, ecp ); + _routingGraph->createVEdge ( from, to, vecp ); } } _matrix.push_back ( vect ); diff --git a/knik/src/Vertex.cpp b/knik/src/Vertex.cpp index f249d035..7b3c2226 100644 --- a/knik/src/Vertex.cpp +++ b/knik/src/Vertex.cpp @@ -505,10 +505,10 @@ string Vertex::_getString() const // ****************************** { return "<" + _TName ( "Vertex" ) - + ":" + getString ( _connexID ) - + " " + getString ( _netStamp ) - + " " + getString ( DbU::getValueString(_position.getX()) ) - + " " + getString ( DbU::getValueString(_position.getY()) ) + ">"; + + " id:" + getString ( _connexID ) + + " s:" + getString ( _netStamp ) + + " " + getString ( DbU::getValueString(_position.getX()) ) + + " " + getString ( DbU::getValueString(_position.getY()) ) + ">"; } Record* Vertex::_getRecord() const diff --git a/knik/src/knik/Edge.h b/knik/src/knik/Edge.h index f12a57f7..7c813fcd 100644 --- a/knik/src/knik/Edge.h +++ b/knik/src/knik/Edge.h @@ -67,7 +67,8 @@ namespace Knik { void setNextFrom ( Edge* edge ) { _nextFrom = edge; }; void setNextTo ( Edge* edge ) { _nextTo = edge; }; void setConnexID ( int connexID ) { _connexID = connexID; }; - void setCapacity ( unsigned capacity ) { _capacity = capacity; }; + //void setCapacity ( unsigned capacity ) { _capacity = capacity; }; + void setCapacity ( unsigned capacity ); void increaseCapacity ( int capacity ); void setCost ( float cost ) { _cost = cost; }; void incCost ( float inc ) { _cost += inc; }; diff --git a/knik/src/knik/Graph.h b/knik/src/knik/Graph.h index 8abc8b4a..4141fa36 100644 --- a/knik/src/knik/Graph.h +++ b/knik/src/knik/Graph.h @@ -1,12 +1,24 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC/LIP6 2006-2014, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K n i k - G l o b a l R o u t e r | +// | | +// | Author : Damien Dupuis | +// | E-mail : Damien.Dupuis@lip6.fr | +// | =============================================================== | +// | C++ Header : "./knik/Graph.h" | +// +-----------------------------------------------------------------+ -#ifndef _KNIK_GRAPH_H -#define _KNIK_GRAPH_H + +#ifndef KNIK_GRAPH_H +#define KNIK_GRAPH_H #include - -//#include "hurricane/viewer/DensityWindow.h" #include "hurricane/RoutingPad.h" - #include "knik/Vertex.h" #include "knik/Vertexes.h" #include "knik/Edge.h" @@ -16,11 +28,12 @@ #include "knik/SlicingTree.h" #include "knik/RoutingGrid.h" -//#include "knik/flute.h" struct FTree; namespace Knik { + class KnikEngine; + class Graph { friend class Vertex; // Types @@ -54,6 +67,7 @@ namespace Knik { // ********** private: Cell* _cell; + KnikEngine* _engine; bool _benchMode; bool _useSegments; SlicingTree* _slicingTree; @@ -85,10 +99,10 @@ namespace Knik { // Constructors & Destructors // ************************** protected: - Graph ( Cell* cell, RoutingGrid* routingGrid, bool benchMode, bool useSegments ); + Graph ( KnikEngine*, RoutingGrid*, bool benchMode, bool useSegments ); ~Graph() {}; public: - static Graph* create ( Cell* cell, RoutingGrid* routingGrid, bool benchMode, bool useSegments ); + static Graph* create ( KnikEngine*, RoutingGrid*, bool benchMode, bool useSegments ); void destroy(); void _postCreate(); void _preDestroy(); @@ -96,24 +110,25 @@ namespace Knik { // Accessors // ********* public: - Cell* getCell() { return _cell; }; - unsigned getNbSplitters() { return _nbSplitters; }; - unsigned getNetStamp() { return _netStamp; }; - Net* getWorkingNet() { return _working_net; }; - Vertex* getPredecessor ( const Vertex* vertex ); - Edge* getEdgeBetween ( Vertex* vertex1, Vertex* vertex2 ); - Edge* getEdge ( unsigned col1, unsigned row1, unsigned col2, unsigned row2 ); - Vertex* getCentralVertex (); - Vertex* getVertex ( Point ); - Vertex* getVertex ( DbU::Unit x, DbU::Unit y ); - Vertexes getVertexes() { return VectorCollection(_all_vertexes); }; - Vertex* getLowerLeftVertex() { return _lowerLeftVertex; }; - unsigned getGridLength ( Segment* segment ); - unsigned getCongestEdgeNb ( Segment* segment ); - size_t getXSize () const { return (_matrixVertex) ? _matrixVertex->getXSize() : 0; }; - size_t getYSize () const { return (_matrixVertex) ? _matrixVertex->getYSize() : 0; }; - float getHEdgeNormalisedLength() const { return _hEdgeNormalisedLength; }; - float getVEdgeNormalisedLength() const { return _vEdgeNormalisedLength; }; + KnikEngine* getEngine () { return _engine; } + Cell* getCell () { return _cell; }; + unsigned getNbSplitters () { return _nbSplitters; }; + unsigned getNetStamp () { return _netStamp; }; + Net* getWorkingNet () { return _working_net; }; + Vertex* getPredecessor ( const Vertex* vertex ); + Edge* getEdgeBetween ( Vertex* vertex1, Vertex* vertex2 ); + Edge* getEdge ( unsigned col1, unsigned row1, unsigned col2, unsigned row2 ); + Vertex* getCentralVertex (); + Vertex* getVertex ( Point ); + Vertex* getVertex ( DbU::Unit x, DbU::Unit y ); + Vertexes getVertexes () { return VectorCollection(_all_vertexes); }; + Vertex* getLowerLeftVertex () { return _lowerLeftVertex; }; + unsigned getGridLength ( Segment* segment ); + unsigned getCongestEdgeNb ( Segment* segment ); + size_t getXSize () const { return (_matrixVertex) ? _matrixVertex->getXSize() : 0; }; + size_t getYSize () const { return (_matrixVertex) ? _matrixVertex->getYSize() : 0; }; + float getHEdgeNormalisedLength() const { return _hEdgeNormalisedLength; }; + float getVEdgeNormalisedLength() const { return _vEdgeNormalisedLength; }; // Modifiers // ********* diff --git a/knik/src/knik/KnikEngine.h b/knik/src/knik/KnikEngine.h index a5d3f9c8..c60ae998 100644 --- a/knik/src/knik/KnikEngine.h +++ b/knik/src/knik/KnikEngine.h @@ -1,40 +1,30 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC/LIP6 2006-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | -// | Knik - Global Router | +// | K n i k - G l o b a l R o u t e r | // | | // | Author : Damien Dupuis | // | E-mail : Damien.Dupuis@lip6.fr | // | =============================================================== | -// | C++ Header : "./KnikEngine.h" | -// | *************************************************************** | -// | Date : 30/10/2006 | -// | | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./knik/KnikEngine.h" | +// +-----------------------------------------------------------------+ #include "hurricane/Timer.h" #include "hurricane/Property.h" #include "hurricane/Net.h" #include "hurricane/RoutingPad.h" - -//#include "CEditor.h" #include "crlcore/ToolEngine.h" +namespace CRL { + class RoutingGauge; +} -#ifndef _KNIK_H -#define _KNIK_H +#ifndef KNIK_KNIKENGINE_H +#define KNIK_KNIKENGINE_H namespace Knik { @@ -57,6 +47,7 @@ using Hurricane::Net; using Hurricane::Segment; using Hurricane::Contact; using Hurricane::Cell; +using CRL::RoutingGauge; class Vertex; @@ -129,7 +120,10 @@ typedef vector NetVector; // ********** private: static const Name _toolName; - static float _edgeCapacityPercent; + static float _edgeHCapacityPercent; + static float _edgeVCapacityPercent; + RoutingGauge* _routingGauge; + unsigned int _allowedDepth; Graph* _routingGraph; RoutingGrid* _routingGrid; Timer _timer; @@ -165,39 +159,48 @@ typedef vector NetVector; // private: void RestructureNet ( Net* net ); // private: void createLimitedZone ( Net* net, set gcells, Box vertexCenterBoundingBox, unsigned netStamp ); string adaptString ( string s ); - public: - static void setEdgeCapacityPercent ( float ecp ) { _edgeCapacityPercent = ecp; }; - void initGlobalRouting(); // Making it public, so it can be called earlier and then capacities on edges can be ajusted - void run(); - void Route(); - void createRoutingGrid ( unsigned nbXTiles - , unsigned nbYTiles - , const Box& boundingBox - , DbU::Unit tileWidth - , DbU::Unit tileHeight - , unsigned hcapacity - , unsigned vcapacity ); - void updateEdgeCapacity ( unsigned col1, unsigned row1, unsigned col2, unsigned row2, unsigned capacity ); - void increaseEdgeCapacity ( unsigned col1, unsigned row1, unsigned col2, unsigned row2, int capacity ); - void insertSegment ( Segment* segment ); - bool analyseRouting(); - void unrouteOvSegments(); - void reroute(); - void unrouteSelected(); - // for ispd07 reload - void createRoutingGraph(); - void addRoutingPadToGraph ( Hurricane::RoutingPad* routingPad ); - inline Graph* getRoutingGraph() { return _routingGraph; } - Vertex* getVertex ( Point ); - Vertex* getVertex ( DbU::Unit x, DbU::Unit y ); - Edge* getEdge ( unsigned col1, unsigned row1, unsigned col2, unsigned row2 ); + public: + static void setHEdgeCapacityPercent ( float ecp ) { _edgeHCapacityPercent = ecp; }; + static void setVEdgeCapacityPercent ( float ecp ) { _edgeVCapacityPercent = ecp; }; + void setRoutingGauge ( RoutingGauge* ); + RoutingGauge* getRoutingGauge () const { return _routingGauge; } + void setAllowedDepth ( unsigned int ); + unsigned int getAllowedDepth () const { return _allowedDepth; } + void initGlobalRouting (); // Making it public, so it can be called earlier and then capacities on edges can be ajusted + void run (); + void Route (); + void createRoutingGrid ( unsigned nbXTiles + , unsigned nbYTiles + , const Box& boundingBox + , DbU::Unit tileWidth + , DbU::Unit tileHeight + , unsigned hcapacity + , unsigned vcapacity ); + void updateEdgeCapacity ( unsigned col1, unsigned row1 + , unsigned col2, unsigned row2, unsigned capacity ); + void increaseEdgeCapacity ( unsigned col1, unsigned row1 + , unsigned col2, unsigned row2, int capacity ); + void insertSegment ( Segment* segment ); + bool analyseRouting (); + void unrouteOvSegments (); + void reroute (); + void unrouteSelected (); + // for ispd07 reload + void createRoutingGraph (); + void addRoutingPadToGraph ( Hurricane::RoutingPad* routingPad ); + inline Graph* getRoutingGraph () { return _routingGraph; } + Vertex* getVertex ( Point ); + Vertex* getVertex ( DbU::Unit x, DbU::Unit y ); + Edge* getEdge ( unsigned col1, unsigned row1 + , unsigned col2, unsigned row2 ); // Others // ****** public: static KnikEngine* get ( const Cell* ); static const Name& staticGetName () { return _toolName; }; - static float getEdgeCapacityPercent () { return _edgeCapacityPercent; }; + static float getHEdgeCapacityPercent () { return _edgeHCapacityPercent; }; + static float getVEdgeCapacityPercent () { return _edgeVCapacityPercent; }; const Name& getName () const { return _toolName; }; void printTime (); void computeOverflow (); diff --git a/knik/src/knik/STuple.h b/knik/src/knik/STuple.h index fd8a7813..911de661 100644 --- a/knik/src/knik/STuple.h +++ b/knik/src/knik/STuple.h @@ -23,17 +23,18 @@ namespace Knik { assert ( segment2 ); if ( segment1->getSourceX() < segment2->getSourceX() ) return true; if ( segment1->getSourceX() == segment2->getSourceX() ) { - if ( segment1->getSourceY() < segment2->getSourceY() ) return true; - if ( segment1->getSourceY() == segment2->getSourceY() ) { - // nous avons deux segemnts de meme cout exactement superposés - // il n'est pas possible qu'ils aient le meme net ! - if (getString(segment1->getNet()->getName()) < getString(segment2->getNet()->getName()) ) return true; - if (getString(segment1->getNet()->getName()) == getString(segment2->getNet()->getName()) ) { - cerr << segment1 << endl; - cerr << segment2 << endl; - assert(false); - } - } + if ( segment1->getSourceY() < segment2->getSourceY() ) return true; + if ( segment1->getSourceY() == segment2->getSourceY() ) { + // segment1 & segment2 are superposed and with exactly the same cost. + // They musn't belong to the same net. + // CURRENTLY DISABLED THIS CHECK MAY BE INACCURATE. + if (getString(segment1->getNet()->getName()) < getString(segment2->getNet()->getName()) ) return true; + // if (getString(segment1->getNet()->getName()) == getString(segment2->getNet()->getName()) ) { + // cerr << segment1 << endl; + // cerr << segment2 << endl; + // //assert(false); + // } + } } } return false; diff --git a/knik/src/knik/VTuple.h b/knik/src/knik/VTuple.h index b44ab360..7f98aaad 100644 --- a/knik/src/knik/VTuple.h +++ b/knik/src/knik/VTuple.h @@ -46,7 +46,7 @@ namespace Knik { public: Vertex* getVertex() const { return _vertex; } float getDistance() const { return _distance; } - string _getString() const { string s = " -#include - #include #include #include @@ -42,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +54,7 @@ namespace Mauka { using Hurricane::Graphics; using Hurricane::ColorScale; using Hurricane::ControllerWidget; + using Hurricane::ExceptionWidget; using CRL::Catalog; using CRL::getInstancesCount; using CRL::AllianceFramework; @@ -140,111 +130,110 @@ namespace Mauka { } - MaukaEngine* GraphicMaukaEngine::getForFramework () + MaukaEngine* GraphicMaukaEngine::getForFramework ( unsigned int flags ) { - MaukaEngine* mauka = MaukaEngine::get ( getCell() ); - if ( mauka != NULL ) return mauka; + MaukaEngine* mauka = MaukaEngine::get( getCell() ); + if (mauka) return mauka; - mauka = createEngine (); - - if ( mauka == NULL ) - throw Error("Failed to create Mauka engine on %s.",getString(getCell()).c_str()); + if (flags & CreateEngine) { + mauka = createEngine(); + if (not mauka) + throw Error( "Failed to create Mauka engine on %s.", getString(getCell()).c_str() ); + } else { + throw Error( "MaukaEngine not created yet, out of sequence action." ); + } return mauka; } - void GraphicMaukaEngine::doQuadriPart () + void GraphicMaukaEngine::_doQuadriPart () { if ( not MetisEngine::isHMetisCapable() ) { cerr << Warning("Mauka has not been compiled againts hMETIS.\n" " Quadri-partition step is disabled, simulated annealing may be *very* long." ) << endl; return; } - Cell* cell = getCell (); + Cell* cell = getCell(); - emit cellPreModificated (); - - NimbusEngine* nimbus = NimbusEngine::get ( cell ); - if ( nimbus == NULL ) { - nimbus = NimbusEngine::create ( cell ); - if ( cmess1.enabled() ) + NimbusEngine* nimbus = NimbusEngine::get( cell ); + if (nimbus == NULL) { + nimbus = NimbusEngine::create( cell ); + if (cmess1.enabled()) nimbus->getConfiguration()->print( cell ); } - MetisEngine* metis = MetisEngine::get ( cell ); - if ( metis == NULL ) { - metis = MetisEngine ::create ( cell ); - if ( getInstancesCount(cell) < metis->getNumberOfInstancesStopCriterion()*4 ) + MetisEngine* metis = MetisEngine::get( cell ); + if (metis == NULL) { + metis = MetisEngine ::create( cell ); + if (getInstancesCount(cell) < metis->getNumberOfInstancesStopCriterion()*4) return; - if ( cmess1.enabled() ) + if (cmess1.enabled()) metis->getConfiguration()->print( cell ); } - metis->setRefreshCb ( boost::bind(&GraphicMaukaEngine::refreshViewer,this) ); + metis->setRefreshCb( std::bind(&GraphicMaukaEngine::refreshViewer,this) ); - MetisEngine::doQuadriPart ( cell ); + MetisEngine::doQuadriPart( cell ); - MaukaEngine* mauka = MaukaEngine::get ( cell ); - if ( mauka != NULL ) + MaukaEngine* mauka = MaukaEngine::get( cell ); + if (mauka != NULL) throw Warning("GraphicMaukaEngine::doQuadriPart(): Placement already done on <%s>" ,getString(cell->getName()).c_str()); mauka = createEngine(); - MaukaEngine::regroupOverloadedGCells ( cell ); + MaukaEngine::regroupOverloadedGCells( cell ); - _viewer->clearToolInterrupt (); - _viewer->getCellWidget()->fitToContents (); - - //mauka->Run (); - emit cellPostModificated (); + _viewer->clearToolInterrupt(); + _viewer->getCellWidget()->fitToContents(); } - void GraphicMaukaEngine::doSimulatedAnnealing () + void GraphicMaukaEngine::_doSimulatedAnnealing () { - MaukaEngine* mauka = createEngine (); - if ( mauka == NULL ) { - throw Error("MaukaEngine not created yet, run the global router first."); - } - mauka->setRefreshCb ( boost::bind(&GraphicMaukaEngine::refreshViewer,this) ); - emit cellPreModificated (); + MaukaEngine* mauka = getForFramework( CreateEngine ); + mauka->setRefreshCb ( std::bind(&GraphicMaukaEngine::refreshViewer,this) ); _viewer->clearToolInterrupt (); _viewer->getCellWidget()->fitToContents (); mauka->Run (); - emit cellPostModificated (); } void GraphicMaukaEngine::place () { - if ( MetisEngine::isHMetisCapable() ) { - doQuadriPart (); + if (MetisEngine::isHMetisCapable()) { + doQuadriPart(); } else { cerr << Warning("Mauka has not been compiled againts hMETIS.\n" " Quadri-partition step is disabled, simulated annealing may be *very* long." ) << endl; } - doSimulatedAnnealing (); - save (); + doSimulatedAnnealing(); + save(); } + void GraphicMaukaEngine::_save () + { + MaukaEngine* mauka = getForFramework( NoFlags ); + + _viewer->clearToolInterrupt (); + mauka->Save (); + } + + + void GraphicMaukaEngine::doQuadriPart () + { ExceptionWidget::catchAllWrapper( std::bind(&GraphicMaukaEngine::_doQuadriPart,this) ); } + + + void GraphicMaukaEngine::doSimulatedAnnealing () + { ExceptionWidget::catchAllWrapper( std::bind(&GraphicMaukaEngine::_doSimulatedAnnealing,this) ); } + + void GraphicMaukaEngine::save () - { - MaukaEngine* mauka = createEngine (); - if ( mauka == NULL ) { - throw Error("MaukaEngine not created yet, run the placer first."); - } - emit cellPreModificated (); - - _viewer->clearToolInterrupt (); - - mauka->Save (); - emit cellPostModificated (); - } + { ExceptionWidget::catchAllWrapper( std::bind(&GraphicMaukaEngine::_save,this) ); } void GraphicMaukaEngine::addToMenu ( CellViewer* viewer ) @@ -297,9 +286,6 @@ namespace Mauka { connect ( placeAction , SIGNAL(triggered()), this, SLOT(place()) ); } - connect ( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) ); - connect ( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) ); - // ControllerWidget* controller = _viewer->getControllerWidget(); // ConfigurationWidget* setting = controller->getSettings() // ->findChild("controller.tabSettings.setting.mauka"); diff --git a/mauka/src/mauka/Configuration.h b/mauka/src/mauka/Configuration.h index 769ccc16..d32f74b3 100644 --- a/mauka/src/mauka/Configuration.h +++ b/mauka/src/mauka/Configuration.h @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | M a u k a - P l a c e r | // | | @@ -17,17 +11,14 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Header : "./Configuration.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __MAUKA_CONFIGURATION__ -#define __MAUKA_CONFIGURATION__ +#ifndef MAUKA_CONFIGURATION_H +#define MAUKA_CONFIGURATION_H #include -#include +#include #include "crlcore/CellGauge.h" namespace Hurricane { @@ -50,7 +41,7 @@ namespace Mauka { class Configuration { public: - typedef boost::function< void(void) > RefreshCb_t; + typedef std::function< void(void) > RefreshCb_t; public: // Constructor & Destructor. Configuration ( CellGauge* cg=NULL ); @@ -125,16 +116,14 @@ namespace Mauka { Configuration::getRefreshCb () { return _refreshCb; } inline double Configuration::_normPercentage ( double ratio, double min, double max ) { - if ( ratio < min ) return min; - if ( ratio > max ) return max; + if (ratio < min) return min; + if (ratio > max) return max; return ratio; } -} // End of Mauka namespace. - +} // Mauka namespace. INSPECTOR_P_SUPPORT(Mauka::Configuration); - -#endif // __MAUKA_CONFIGURATION__ +#endif // MAUKA_CONFIGURATION_H diff --git a/mauka/src/mauka/GraphicMaukaEngine.h b/mauka/src/mauka/GraphicMaukaEngine.h index 7c8b03e2..a69567e8 100644 --- a/mauka/src/mauka/GraphicMaukaEngine.h +++ b/mauka/src/mauka/GraphicMaukaEngine.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,8 +14,8 @@ // +-----------------------------------------------------------------+ -#ifndef __MAUKA_GRAPHIC_MAUKA_ENGINE__ -#define __MAUKA_GRAPHIC_MAUKA_ENGINE__ +#ifndef MAUKA_GRAPHIC_MAUKA_ENGINE_H +#define MAUKA_GRAPHIC_MAUKA_ENGINE_H #include @@ -50,9 +49,12 @@ namespace Mauka { class GraphicMaukaEngine : public GraphicTool { Q_OBJECT; + public: + enum Flags { NoFlags=0x0000, CreateEngine=0x0001 }; + public: MaukaEngine* createEngine (); - MaukaEngine* getForFramework (); + MaukaEngine* getForFramework ( unsigned int flags ); static void initMaukaContainer ( CellWidget* ); static void drawMaukaContainer ( CellWidget* , const Go* @@ -77,12 +79,14 @@ namespace Mauka { static GraphicMaukaEngine* _singleton; CellViewer* _viewer; protected: - GraphicMaukaEngine (); - virtual ~GraphicMaukaEngine (); + GraphicMaukaEngine (); + virtual ~GraphicMaukaEngine (); + void _doQuadriPart (); + void _doSimulatedAnnealing (); + void _save (); }; -} // End of Mauka namespace. +} // Mauka namespace. - -#endif // __MAUKA_GRAPHIC_MAUKA_ENGINE__ +#endif // MAUKA_GRAPHIC_MAUKA_ENGINE_H diff --git a/mauka/src/mauka/MaukaEngine.h b/mauka/src/mauka/MaukaEngine.h index 268b919f..77dde454 100644 --- a/mauka/src/mauka/MaukaEngine.h +++ b/mauka/src/mauka/MaukaEngine.h @@ -1,10 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2006-2013, All Rights Reserved +// Copyright (c) UPMC/LIP6 2006-2014, All Rights Reserved // -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | M a u k a - P l a c e r | // | | @@ -12,11 +11,11 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./mauka/MaukaEngine.h" | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __MAUKA_ENGINE_H -#define __MAUKA_ENGINE_H +#ifndef MAUKA_ENGINE_H +#define MAUKA_ENGINE_H #include "hurricane/Instance.h" #include "crlcore/ToolEngine.h" @@ -169,6 +168,6 @@ namespace Mauka { bool TestMaukaConstruction(Cell* cell, GCell* gcell); -} // Enf of Mauka namespace. +} // Mauka namespace. -#endif // __MAUKA_ENGINE_H +#endif // MAUKA_ENGINE_H diff --git a/metis/src/MetisGraph.cpp b/metis/src/MetisGraph.cpp index f54e6a7f..275c07b4 100644 --- a/metis/src/MetisGraph.cpp +++ b/metis/src/MetisGraph.cpp @@ -33,6 +33,8 @@ #ifdef HAVE_HMETIS_LIB +#include + #include "hurricane/Net.h" #include "hurricane/Instance.h" #include "hurricane/Plug.h" diff --git a/metis/src/metis/Configuration.h b/metis/src/metis/Configuration.h index 09617a3b..79519aee 100644 --- a/metis/src/metis/Configuration.h +++ b/metis/src/metis/Configuration.h @@ -1,33 +1,24 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | M e t i s - h M e t i s W r a p p e r | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./Configuration.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./metis/Configuration.h" | +// +-----------------------------------------------------------------+ -#ifndef __METIS_CONFIGURATION__ -#define __METIS_CONFIGURATION__ +#ifndef METIS_CONFIGURATION_H +#define METIS_CONFIGURATION_H #include -#include +#include namespace Hurricane { class Record; @@ -47,7 +38,7 @@ namespace Metis { class Configuration { public: - typedef boost::function< void(void) > RefreshCb_t; + typedef std::function< void(void) > RefreshCb_t; public: enum MetisOption { CustomOptions =0 , HMetisNRuns =1 @@ -139,10 +130,8 @@ namespace Metis { { if (optioncompare (); - emit cellPostModificated (); + //emit cellPostModificated (); _viewer->dumpObjectTree(); QTabWidget* ctrlTab = _viewer->getControllerWidget(); if (ctrlTab) { diff --git a/unicorn/src/cgt.py b/unicorn/src/cgt.py index 37f27f99..0d050b84 100755 --- a/unicorn/src/cgt.py +++ b/unicorn/src/cgt.py @@ -84,31 +84,33 @@ if __name__ == '__main__': usage += '\ncgt [options]' parser = optparse.OptionParser(usage) - parser.add_option( '-c', '--cell' , type='string' , dest='cell' , help='The name of the cell to load, whithout extension.') - parser.add_option( '--acm-sigda-89' , type='string' , dest='acmSigdaName' , help='An ACM/SIGDA 89 bench name to load, whithout extension.') - parser.add_option( '--ispd-05' , type='string' , dest='ispd05name' , help='An ISPD 05 bench (placement) name to load, whithout extension.') - parser.add_option( '--script' , type='string' , dest='script' , help='Run a Python or Stratus script.') - parser.add_option( '-v', '--verbose' , action='store_true', dest='verbose' , help='First level of verbosity.') - parser.add_option( '-V', '--very-verbose' , action='store_true', dest='veryVerbose' , help='Second level of verbosity.') - parser.add_option( '-i', '--info' , action='store_true', dest='info' , help='Display lots of informational messages.') - parser.add_option( '--paranoid' , action='store_true', dest='paranoid' , help='Display everything that *may be* suspicious...') - parser.add_option( '-b', '--bug' , action='store_true', dest='bug' , help='Display bug related messages.') - parser.add_option( '--show-conf' , action='store_true', dest='showConf' , help='Display Kite configuration.') - parser.add_option( '-D', '--core-dump' , action='store_true', dest='coreDump' , help='Enable core-dump when a crash occurs.') - parser.add_option( '-L', '--log-mode' , action='store_true', dest='logMode' , help='Disable ANSI escape sequences in console output.') - parser.add_option( '-t', '--text' , action='store_true', dest='textMode' , help='Run in command line mode.') - parser.add_option( '-m', '--margin' , type='float' , dest='margin' , help='Percentage of free area to add to the minimal placement area.') - parser.add_option( '-Q', '--quadri-place' , action='store_true', dest='quadPlace' , help='Performs a quadri-partitionnement as first placement stage.') - parser.add_option( '-P', '--annealing' , action='store_true', dest='annealingPlace', help='Place using simulated annealing.') - parser.add_option( '--min-psize' , type='int' , dest='minPSize' , help='Sets the size of a leaf partition (quadripartition stage).') - parser.add_option( '-G', '--global-route' , action='store_true', dest='globalRoute' , help='Run the global router (Knik).') - parser.add_option( '-g', '--load-global' , action='store_true', dest='loadGlobal' , help='Reload a global routing from disk.') - parser.add_option( '--save-global' , action='store_true', dest='saveGlobal' , help='Save the global routing solution.') - parser.add_option( '-e', '--edge' , type='float' , dest='edgeCapacity' , help='The egde density ratio applied on global router\'s edges.') - parser.add_option( '--events-limit' , type='int' , dest='eventsLimit' , help='The maximum number of iterations (events) that the router is allowed to perform.') - parser.add_option( '-R', '--detail-route' , action='store_true', dest='detailRoute' , help='Run the detailed router (Kite).') - parser.add_option( '-M', '--dump-measures' , action='store_true', dest='dumpMeasures' , help='Dump some statistical measurements on the disk.') - parser.add_option( '-s', '--save-design' , type='string' , dest='saveDesign' , help='Save the routed design.') + parser.add_option( '-c', '--cell' , type='string' , dest='cell' , help='The name of the cell to load, whithout extension.') + parser.add_option( '--acm-sigda-89' , type='string' , dest='acmSigdaName' , help='An ACM/SIGDA 89 bench name to load, whithout extension.') + parser.add_option( '--ispd-05' , type='string' , dest='ispd05name' , help='An ISPD 05 bench (placement) name to load, whithout extension.') + parser.add_option( '--script' , type='string' , dest='script' , help='Run a Python or Stratus script.') + parser.add_option( '-v', '--verbose' , action='store_true', dest='verbose' , help='First level of verbosity.') + parser.add_option( '-V', '--very-verbose' , action='store_true', dest='veryVerbose' , help='Second level of verbosity.') + parser.add_option( '-i', '--info' , action='store_true', dest='info' , help='Display lots of informational messages.') + parser.add_option( '--paranoid' , action='store_true', dest='paranoid' , help='Display everything that *may be* suspicious...') + parser.add_option( '-b', '--bug' , action='store_true', dest='bug' , help='Display bug related messages.') + parser.add_option( '--show-conf' , action='store_true', dest='showConf' , help='Display Kite configuration.') + parser.add_option( '-D', '--core-dump' , action='store_true', dest='coreDump' , help='Enable core-dump when a crash occurs.') + parser.add_option( '-L', '--log-mode' , action='store_true', dest='logMode' , help='Disable ANSI escape sequences in console output.') + parser.add_option( '-t', '--text' , action='store_true', dest='textMode' , help='Run in command line mode.') + parser.add_option( '-m', '--margin' , type='float' , dest='margin' , help='Percentage of free area to add to the minimal placement area.') + parser.add_option( '-Q', '--quadri-place' , action='store_true', dest='quadPlace' , help='Performs a quadri-partitionnement as first placement stage.') + parser.add_option( '-P', '--annealing' , action='store_true', dest='annealingPlace' , help='Place using simulated annealing.') + parser.add_option( '--min-psize' , type='int' , dest='minPSize' , help='Sets the size of a leaf partition (quadripartition stage).') + parser.add_option( '-G', '--global-route' , action='store_true', dest='globalRoute' , help='Run the global router (Knik).') + parser.add_option( '-g', '--load-global' , action='store_true', dest='loadGlobal' , help='Reload a global routing from disk.') + parser.add_option( '--save-global' , action='store_true', dest='saveGlobal' , help='Save the global routing solution.') + parser.add_option( '--h-edge' , type='float' , dest='hEdgeCapacity' , help='The horizontal egde density ratio applied on global router\'s edges.') + parser.add_option( '--v-edge' , type='float' , dest='vEdgeCapacity' , help='The vertical egde density ratio applied on global router\'s edges.') + parser.add_option( '--events-limit' , type='int' , dest='eventsLimit' , help='The maximum number of iterations (events) that the router is allowed to perform.') + parser.add_option( '-R', '--detail-route' , action='store_true', dest='detailRoute' , help='Run the detailed router (Kite).') + parser.add_option( '-M', '--dump-measures' , action='store_true', dest='dumpMeasures' , help='Dump some statistical measurements on the disk.') + parser.add_option( '-s', '--save-design' , type='string' , dest='saveDesign' , help='Save the routed design.') + parser.add_option( '--top-routing-layer', type='string' , dest='topRoutingLayer', help='Sets the top (upper) routing layer.') (options, args) = parser.parse_args() args.insert(0, 'cgt') @@ -117,18 +119,20 @@ if __name__ == '__main__': #Hurricane.trace(True) Cfg.Configuration.pushDefaultPriority(Cfg.Parameter.Priority.CommandLine) - if options.coreDump: Cfg.getParamBool ('misc.catchCore' ).setBool(False) - if options.verbose: Cfg.getParamBool ('misc.verboseLevel1').setBool(True) - if options.veryVerbose: Cfg.getParamBool ('misc.verboseLevel2').setBool(True) - if options.info: Cfg.getParamBool ('misc.info' ).setBool(True) - if options.paranoid: Cfg.getParamBool ('misc.paranoid' ).setBool(True) - if options.bug: Cfg.getParamBool ('misc.bug' ).setBool(True) - if options.logMode: Cfg.getParamBool ('misc.logMode' ).setBool(True) - if options.showConf: Cfg.getParamBool ('misc.showConf' ).setBool(True) - if options.margin: Cfg.getParamPercentage('nimbus.spaceMargin').setPercentage(options.margin) - if options.minPSize: Cfg.getParamInt ('metis.numberOfInstancesStopCriterion').setInt(options.minPSize) - if options.edgeCapacity: Cfg.getParamPercentage('kite.edgeCapacity' ).setPercentage(options.edgeCapacity) - if options.eventsLimit: Cfg.getParamInt ('kite.eventsLimit' ).setInt(options.eventsLimit) + if options.coreDump: Cfg.getParamBool ('misc.catchCore' ).setBool(False) + if options.verbose: Cfg.getParamBool ('misc.verboseLevel1').setBool(True) + if options.veryVerbose: Cfg.getParamBool ('misc.verboseLevel2').setBool(True) + if options.info: Cfg.getParamBool ('misc.info' ).setBool(True) + if options.paranoid: Cfg.getParamBool ('misc.paranoid' ).setBool(True) + if options.bug: Cfg.getParamBool ('misc.bug' ).setBool(True) + if options.logMode: Cfg.getParamBool ('misc.logMode' ).setBool(True) + if options.showConf: Cfg.getParamBool ('misc.showConf' ).setBool(True) + if options.margin: Cfg.getParamPercentage('nimbus.spaceMargin').setPercentage(options.margin) + if options.minPSize: Cfg.getParamInt ('metis.numberOfInstancesStopCriterion').setInt(options.minPSize) + if options.hEdgeCapacity: Cfg.getParamPercentage('kite.hEdgeCapacity').setPercentage(options.hEdgeCapacity) + if options.vEdgeCapacity: Cfg.getParamPercentage('kite.vEdgeCapacity').setPercentage(options.vEdgeCapacity) + if options.eventsLimit: Cfg.getParamInt ('kite.eventsLimit' ).setInt(options.eventsLimit) + if options.topRoutingLayer: Cfg.getParamString ('katabatic.topRoutingLayer').setString(options.topRoutingLayer) quadPlace = options.quadPlace annealingPlace = options.annealingPlace @@ -219,7 +223,7 @@ if __name__ == '__main__': routingNets = [] kite = Kite.KiteEngine.create(cell) - if options.showConf: kite.printConfiguration() + if options.showConf: kite.printConfiguration() kite.runGlobalRouter(globalFlags) if saveGlobal: kite.saveGlobalSolution() diff --git a/vlsisapd/src/configuration/src/Configuration.cpp b/vlsisapd/src/configuration/src/Configuration.cpp index 1b14014a..64d04022 100644 --- a/vlsisapd/src/configuration/src/Configuration.cpp +++ b/vlsisapd/src/configuration/src/Configuration.cpp @@ -1,12 +1,7 @@ - // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved -// -// =================================================================== -// -// $Id$ +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/vlsisapd/src/configuration/src/PyConfiguration.cpp b/vlsisapd/src/configuration/src/PyConfiguration.cpp index f27efdbf..38c6f650 100644 --- a/vlsisapd/src/configuration/src/PyConfiguration.cpp +++ b/vlsisapd/src/configuration/src/PyConfiguration.cpp @@ -326,6 +326,7 @@ namespace Cfg { ; } + def("hasParameter" , hasParameter ); def("getParamString" , getParamString1 , return_value_policy()); def("getParamString" , getParamString2 , return_value_policy()); def("getParamBool" , getParamBool1 , return_value_policy()); diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h index 80f300a5..c1b8af95 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the VSLSI Stand-Alone Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,8 +14,8 @@ // +-----------------------------------------------------------------+ -#ifndef __CFG_CONFIGURATION__ -#define __CFG_CONFIGURATION__ +#ifndef CFG_CONFIGURATION_H +#define CFG_CONFIGURATION_H #include #include @@ -135,6 +134,12 @@ namespace Cfg { } + inline bool hasParameter ( const std::string& id ) + { + return (Configuration::get()->getParameter(id,Parameter::Unknown) != NULL); + } + + inline Parameter* getParamString ( const std::string& id, const std::string& value="" ) { Parameter* parameter = Configuration::get()->getParameter(id,Parameter::String); @@ -231,7 +236,7 @@ namespace Cfg { -} // End of Cfg namespace. +} // Cfg namespace. -#endif // __CFG_CONFIGURATION__ +#endif // CFG_CONFIGURATION_H