Improved UpdateSession & exception catching. Start of RoutingGauge implem.

Miscellaneous:
* Change: In <crlcore>, in display.conf use the same display threshold
    for both METAL2 & METAL3.
      In alliance.conf, the side of VIAs in the gauge is 2l (not 3l).
      In kite.conf, separate edge densities for H/V.
* Change: In <Cell>, in flattenNets() use flag as argument, not a
    boolean. Do not create rings for clock or supply nets.
* Change: In <DeepNet>, in _createRoutingPads() do not create rings
    for clock or supply net (duplicated policy as in Cell::flattenNets()).
* Bug: In <ControllerWidget>, at last find the bad signal disconnect
    that was causing ungraceful messages.
* Change: In <knik>, in Edge display occupancy/capacity in the string
    name. Improved display progress and debugging capabilities.

Improved exception catch & breakpoint managment:
* Bug: In <PaletteWidget>, in updateExtensions() replace the calls to
    deleteLayer() by delete. This cause the widget to be immediatly
    erased instead of waiting for the event queue to be completly
    processed. This was causing the widget to be left in a incoherent
    state when stoping at a breakpoint.
* Bug: In <BreakpointWidget>, in execNoModal(), flush the main event
    loop (QApplication::flush()) *before* lauching the *local* event
    loop. This is to ensure all widgets are in their final state when
    waiting (especially <PaletteWidget>).
* Change: In <ExceptionWidget>, new method catchAllWrapper() to
    execute any std::function< void() > function/method with a "try"/
    "catch" wraparound and lauch the widget in case something is catch.
* New: In <hurricane>, support for a oberver pattern, backported from
    <katabatic> with an Obervable capable of being linked to any
    number of Obervers.
* New: In <Cell>, made it observable to detect Cell change, currently
    emit two kind of signals:
    - Cell::CellAboutToChange : *before* any change.
    - Cell::CellChanged : *after* the change has been completed.
* New: In <UpdateSession>, in Go::invalidate() add the Cell owning the
    Go to the UPDATOR_STACK (of course the cell is added only once).
    In addition, when the Cell is added, send a notification of
    Cell::CellAboutToChange to all it's observers. The slave instances
    are also invalidated.
      Conversely in UpdateSession::_preDestroy() for each invalidated
    Cell send a Cell::CellChanged notification to all observer.
      The UPDATOR_STACK has been slightly amended to accept Cell which
    are not Gos. Prior to this, the Cell where completly excluded from
    the UpdateSession mechanism, so it's instances where never actualised
    of anything referring to the Cell for that matter.
      Note: we use two different mechanisms to transmit a Cell change,
    observers and the slave instance map. I think at some point it
    should be unificated.
* Change: In <CellViewer>, make it a Cell observer to redraw when the
    cell is modificated (also update the palette).
      Uses the catchAllWrapper() to protect all critical actions.
* Change: In <GraphicTool>, no longer need of cellPreModificated and
    cellPostModificated signals. Now done through the Cell obersvers.
* Change: In <mauka>, <etesian> & <kite> now uses the catchAllWrapper
    method for protection (need to split methods in two, to be able
    to pass it as argument). No longer emit cellPreModificated and
    cellPostModificated.

Support for RoutingGauge in P&R:
* Bug: In <placeandroute.py>, the connection from the internal power
    ring to the connectors was not done correctly. Wrong contact layers
    leading to a gap.
* Change: In <BuildPowerRails>, detection of the corona signals based
    on how the "pck_px" pad is connected. No longer based on name
    matching.
* Change: In <placeandroute.py>, support for 2 routing metal only
    (3 metal in the technology).
* Change: In <katabatic> & <kite> support for a "top layer" limitation
    on the routing gauge, this allows to use only two routing metals
    (METAL2 & METAL3). Work in progress.
This commit is contained in:
Jean-Paul Chaput 2014-04-20 19:25:08 +02:00
parent fee45ef117
commit c8bcfdf174
97 changed files with 2634 additions and 1973 deletions

3
.gitignore vendored
View File

@ -3,6 +3,9 @@
*.pyc
*.log
*.bak
TAGS
man/
rtf/
html/

View File

@ -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 ) )
)

View File

@ -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 })

View File

@ -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 } )

View File

@ -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 <iostream>
#include "hurricane/Warning.h"
#include "crlcore/GraphicToolEngine.h"
namespace CRL {
using namespace std;
using Hurricane::Warning;

View File

@ -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 <climits>
#include <sstream>
#include <algorithm>
#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 <climits>
#include <sstream>
#include <algorithm>
#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<const ViaLayer*>(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<RoutingLayerGauge*>& RoutingGauge::getLayerGauges () const
{
return _layerGauges;

View File

@ -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<ToolEngine*>().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 );
}

View File

@ -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 );

View File

@ -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 <string>
#include <map>
#include <functional>
#include <QObject>
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<Name,DrawGoFunctions> 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<Name,DrawGoFunctions> _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

View File

@ -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 <string>
#include <vector>
#include "hurricane/Name.h"
#include "hurricane/Slot.h"
#include <string>
#include <vector>
#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<RoutingLayerGauge*>&
@ -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

View File

@ -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 <map>
#include "hurricane/Commons.h"
#include "hurricane/DbU.h"
#include "hurricane/Collection.h"
#include "hurricane/Slot.h"
#include "crlcore/Utilities.h"
#include <map>
#include "hurricane/Commons.h"
#include "hurricane/DbU.h"
#include "hurricane/Collection.h"
#include "hurricane/Slot.h"
#include "crlcore/Utilities.h"
namespace Hurricane {
class Layer;

View File

@ -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 <string>
#include <vector>
#include "hurricane/Commons.h"
#include "hurricane/DBo.h"
#include "hurricane/Slot.h"
#include <string>
#include <vector>
#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

View File

@ -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 )
##################################### ###########################

View File

@ -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 ();
}

View File

@ -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();

View File

@ -32,6 +32,7 @@
#include <hurricane/viewer/CellWidget.h>
#include <hurricane/viewer/CellViewer.h>
#include <hurricane/viewer/ControllerWidget.h>
#include <hurricane/viewer/ExceptionWidget.h>
#include <crlcore/Utilities.h>
#include <crlcore/AllianceFramework.h>
#include <etesian/GraphicEtesianEngine.h>
@ -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()) );
}

View File

@ -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 ();
};

View File

@ -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

View File

@ -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<Net*>((*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<Plug*>( *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<Plug*>( (*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<Pin*>( *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
// ****************************************************************************************************

View File

@ -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
// <http://www.gnu.org/licenses/>.
//
// ===================================================================
//
// $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 <cstdlib>

View File

@ -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;
}
}

View File

@ -0,0 +1,65 @@
// -*- mode: C++; explicit-buffer-name: "Observer.cpp<hurricane>" -*-
//
// 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 <iostream>
#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<BaseObserver*>::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.

View File

@ -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<Go*>(owner)) ((Go*)owner)->materialize();
end_for;
forEach( DBo*, iowner, getOwners() ) {
Cell* cell = dynamic_cast<Cell*>(*iowner);
if (cell) {
//cerr << "Notify Cell::CellChanged to: " << cell << endl;
cell->notify( Cell::CellChanged );
} else {
Go* go = dynamic_cast<Go*>(*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<Go*>(owner))
throw Error("Bad update session capture : not a graphic object");
void UpdateSession::onCapturedBy(DBo* owner)
// *****************************************
{
if ( not dynamic_cast<Go*>(owner) and not dynamic_cast<Cell*>(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<UpdateSession*>(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<Go*>(it->second);
if (go) go->invalidate(propagateFlag);
}
if (not dynamic_cast<UpdateSession*>(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<Go*>( 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();

View File

@ -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<Entity*,Entity*> 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<Name,ExtensionSlice*> 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);
};

View File

@ -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
// <http://www.gnu.org/licenses/>.
//
// ===================================================================
//
// $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

View File

@ -0,0 +1,109 @@
// -*- mode: C++; explicit-buffer-name: "Observer.h<hurricane>" -*-
//
// 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 <vector>
#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<T*>(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<T>::_ownerOffset = -1;
template< typename T>
inline Observer<T>::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<T>::getOwner () const { return reinterpret_cast<T*>((unsigned long)this - _ownerOffset); }
// -------------------------------------------------------------------
// Class : "Observable".
class Observable {
public:
inline Observable ();
inline std::vector<BaseObserver*> getObservers ();
void addObserver ( BaseObserver* );
void removeObserver ( BaseObserver* );
inline void notify ( unsigned int flags );
private:
Observable ( const Observable& );
private:
std::vector<BaseObserver*> _observers;
};
inline Observable::Observable ()
: _observers()
{ }
inline std::vector<BaseObserver*> Observable::getObservers ()
{ return _observers; }
inline void Observable::notify ( unsigned int flags )
{
for ( auto iobserver : _observers ) {
iobserver->notify( flags );
}
}
} // Hurricane namespace.
#endif

View File

@ -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

View File

@ -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 <QPointer>
#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QSpinBox>
#include <QGridLayout>
#include <QFrame>
#include "hurricane/Breakpoint.h"
#include "hurricane/viewer/BreakpointWidget.h"
#include <QPointer>
#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QSpinBox>
#include <QGridLayout>
#include <QFrame>
#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 ( "<b>No Message Yet</b>" );
@ -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<QDialog> guard = this;
(void)_eventLoop->exec(QEventLoop::DialogExec);
_eventLoop->exec( QEventLoop::DialogExec );
_eventLoop = NULL;
if (guard.isNull()) return QDialog::Rejected;

View File

@ -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 <unistd.h>
#include <algorithm>
#include <sstream>
#include <unistd.h>
#include <algorithm>
#include <sstream>
#include <exception>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QStatusBar>
#include <QDockWidget>
#include <QApplication>
#include <QPrinter>
#include <QPrintDialog>
#include <QFileDialog>
#include "vlsisapd/configuration/Configuration.h"
#include "hurricane/DataBase.h"
#include "hurricane/Cell.h"
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QStatusBar>
#include <QDockWidget>
#include <QApplication>
#include <QPrinter>
#include <QPrintDialog>
#include <QFileDialog>
#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<CellWidget::State>&))
, this , SLOT (setState (shared_ptr<CellWidget::State>&)) );
connect ( this , SIGNAL(stateChanged(shared_ptr<CellWidget::State>&))
, _cellWidget , SLOT (setState (shared_ptr<CellWidget::State>&)) );
connect( _cellWidget , SIGNAL(stateChanged(shared_ptr<CellWidget::State>&))
, this , SLOT (setState (shared_ptr<CellWidget::State>&)) );
connect( this , SIGNAL(stateChanged(shared_ptr<CellWidget::State>&))
, _cellWidget , SLOT (setState (shared_ptr<CellWidget::State>&)) );
_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<CellWidget::State> >::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 ()

View File

@ -1,4 +1,3 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.

View File

@ -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)) );
}
}

View File

@ -1,4 +1,3 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
@ -15,24 +14,24 @@
// +-----------------------------------------------------------------+
#include <unistd.h>
#include <csignal>
#include <memory>
#include <QCloseEvent>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QTextEdit>
#include <QScrollArea>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFrame>
#include <QFont>
#include <QFontMetrics>
#include "hurricane/Error.h"
#include "hurricane/Exception.h"
#include "hurricane/viewer/Graphics.h"
#include "hurricane/viewer/ExceptionWidget.h"
#include <unistd.h>
#include <csignal>
#include <memory>
#include <QCloseEvent>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QTextEdit>
#include <QScrollArea>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFrame>
#include <QFont>
#include <QFontMetrics>
#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 =
"&nbsp;&nbsp;Unmanaged exception, neither a <b>Hurricane::Error</b><br>"
"nor a <b>std::exception</b>.";
ExceptionWidget::run( message );
}
}
ExceptionWidget::ExceptionWidget ( QWidget* parent )
: QDialog (parent)
, _header (new QLabel())

View File

@ -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 <assert.h>
#include <Qt>
#include <QBrush>
#include <QPen>
#include <QApplication>
#include "hurricane/Name.h"
#include "hurricane/Exception.h"
#include "hurricane/viewer/DisplayStyle.h"
#include "hurricane/viewer/Graphics.h"
#include <assert.h>
#include <Qt>
#include <QBrush>
#include <QPen>
#include <QApplication>
#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);
}

View File

@ -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 <QFontMetrics>
#include <QLabel>
#include <QLineEdit>
#include <QHeaderView>
#include <QKeyEvent>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QAction>
#include <QModelIndex>
#include <QFontMetrics>
#include <QLabel>
#include <QLineEdit>
#include <QHeaderView>
#include <QKeyEvent>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QAction>
#include <QModelIndex>
#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;

View File

@ -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 <limits>
#include <QLabel>
#include <QCheckBox>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#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 <limits>
#include <QLabel>
#include <QCheckBox>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#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.

View File

@ -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 |

View File

@ -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 <QEventLoop>
#include <QDialog>
#include <QEventLoop>
#include <QDialog>
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

View File

@ -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 <list>
#ifndef HURRICANE_CELL_VIEWER_H
#define HURRICANE_CELL_VIEWER_H
#include <list>
#include <functional>
using namespace std;
#include <QMainWindow>
#include <QMainWindow>
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<CellViewer> {
public:
inline CellObserver ( CellViewer* );
virtual void notify ( unsigned int flags );
private:
CellObserver ( const CellObserver& );
};
inline CellObserver::CellObserver ( CellViewer* owner )
: Observer<CellViewer>(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<CellWidget::State>& );
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); }

View File

@ -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 <math.h>
#include <vector>
#include <functional>
#include <tr1/memory>
#include <boost/function.hpp>
#include <QWidget>
#include <QPixmap>
#include <QPainter>
#include <QPrinter>
#include <QImage>
#include <QRect>
#include <QPoint>
#ifndef HURRICANE_CELL_WIDGET_H
#define HURRICANE_CELL_WIDGET_H
#include <math.h>
#include <vector>
#include <functional>
#include <tr1/memory>
#include <boost/function.hpp>
#include <QWidget>
#include <QPixmap>
#include <QPainter>
#include <QPrinter>
#include <QImage>
#include <QRect>
#include <QPoint>
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;

View File

@ -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 <exception>
#include <functional>
#include <QDialog>
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

View File

@ -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 <QDialog>
@ -48,8 +39,7 @@ namespace Hurricane {
};
} // End of Hurricane namespace.
} // Hurricane namespace.
#endif // __HURRICANE_SCRIPT_WIDGET__
#endif // HURRICANE_SCRIPT_WIDGET_H

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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) );

View File

@ -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<GCell*> 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<GCell*> 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() );

View File

@ -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) );

View File

@ -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 |

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<katabatic>" -*-
//
// 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 <iostream>
#include <iomanip>
#include <vector>
#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<RoutingLayerGauge*>::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<Katabatic> 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 );
}

View File

@ -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<Axis*> _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<AutoSegment*>::const_iterator isegment;
vector<AutoSegment*>::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<AutoSegment*>::iterator isegment;
vector<AutoSegment*>::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<AutoSegment*>::iterator iend;
set<Net*> 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<AutoSegment*>::iterator isegment;
vector<AutoSegment*>::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 ();

View File

@ -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 |

View File

@ -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();

View File

@ -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<Component*,AutoSegment*>::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 );

View File

@ -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 |

View File

@ -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 ); }

View File

@ -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 <set>
#include <iostream>
#include <functional>
#include <tr1/functional>
#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<AutoSegment*>& );
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); }

View File

@ -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.

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.h<katabatic>" -*-
//
// 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 );
};

View File

@ -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 |

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Session.h<katabatic>" -*-
//
// 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 <boost/function.hpp>
#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<AutoSegment*>& 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); }

View File

@ -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<Hook*> 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) <vdde> net at chip level." ) << endl;
if ( _vsse == NULL ) cerr << Error("Missing (pad) <vsse> net at chip level." ) << endl;
if ( _ck == NULL ) cerr << Warning("No (pad) <ck> net at chip level." ) << endl;
if ( _cki == NULL ) cerr << Warning("No (pad) <cki> net at chip level." ) << endl;
if (hasPad) {
if (_vdde == NULL) cerr << Error("Missing <vdde> net (for pads) at chip level." ) << endl;
else destroyRing( _vdde );
if (_vsse == NULL) cerr << Error("Missing <vsse> net (for pads) at chip level." ) << endl;
else destroyRing( _vsse );
if (_ck == NULL) cerr << Warning("No <ck> net at (for pads) chip level." ) << endl;
if (_cki == NULL) cerr << Warning("No <cki> net at (for pads) chip level." ) << endl;
else destroyRing( _cki );
}
if ( _vddi == NULL ) cerr << Error("Missing <vddi>/<vdd> net at top level." ) << endl;
if ( _vssi == NULL ) cerr << Error("Missing <vssi>/<vss> net at top level." ) << endl;
if ( _ckc == NULL ) cparanoid << Warning("No <ck> net at top level." ) << endl;
if (_vddi == NULL) cerr << Error("Missing <vddi>/<vdd> net (for pads) at top level." ) << endl;
else destroyRing( _vddi );
if (_vssi == NULL) cerr << Error("Missing <vssi>/<vss> net (for pads) at top level." ) << endl;
else destroyRing( _vssi );
if (_cko == NULL) cparanoid << Warning("No <ck> 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)

View File

@ -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<Kite> 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] ) );

View File

@ -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 |

View File

@ -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 <functional>
#include <boost/bind.hpp>
#include <QAction>
#include <QMenu>
@ -33,6 +31,7 @@
#include <hurricane/viewer/CellWidget.h>
#include <hurricane/viewer/CellViewer.h>
#include <hurricane/viewer/ControllerWidget.h>
#include <hurricane/viewer/ExceptionWidget.h>
#include <crlcore/Utilities.h>
#include <crlcore/AllianceFramework.h>
#include <katabatic/GCell.h>
@ -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()) );
}

View File

@ -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 <snx2013>.
//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<tracksSize ; ++itrack ) {
@ -493,7 +505,7 @@ namespace Kite {
//DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_mux32_badr_sd_sel1" );
//DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_addsub32_carith_se_pi_3_21" );
//DebugSession::addToTrace( getCell(), "mips_r3000_1m_ct_cause_rx(1)" );
//Test signals from <MIPS> (R3000,pipeline+chip).
// Test signals from <MIPS> (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 <snx2013>.
//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;

View File

@ -390,11 +390,11 @@ namespace Kite {
RoutingEvent* event = _eventQueue.pop();
if (tty::enabled()) {
cmess2 << " <event:" << tty::bold << setw(7) << setfill('0')
cmess2 << " <event:" << tty::bold << right << setw(7) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
cmess2.flush ();
} else {
cmess2 << " <event:" << setw(7) << setfill('0')
cmess2 << " <event:" << right << setw(7) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << " "
<< event->getEventLevel() << ":" << event->getPriority() << "> "
<< event->getSegment()

View File

@ -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 |

View File

@ -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 <functional>
# 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)

View File

@ -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 |

View File

@ -17,7 +17,7 @@
#ifndef KITE_CONFIGURATION_H
#define KITE_CONFIGURATION_H
#include <boost/function.hpp>
#include <functional>
#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; }

View File

@ -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 <functional>
#include <QObject>
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

View File

@ -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<KatabaticEngine*>(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<TrackElement>(); }
inline CellViewer* KiteEngine::getViewer () const { return _viewer; }
inline KatabaticEngine* KiteEngine::base () { return static_cast<KatabaticEngine*>(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<TrackElement>(); }
// Variables.

View File

@ -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 |

View File

@ -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 |

View File

@ -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

View File

@ -1,8 +1,11 @@
#include <sstream>
#include <algorithm>
#include <memory>
#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<RoutingLayerGauge*> rtLGauges = AllianceFramework::get()->getRoutingGauge()->getLayerGauges();
vector<RoutingLayerGauge*> rtLGauges = _engine->getRoutingGauge()->getLayerGauges();
for ( vector<RoutingLayerGauge*>::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<RoutingLayerGauge*> rtLGauges = AllianceFramework::get()->getRoutingGauge()->getLayerGauges();
for ( vector<RoutingLayerGauge*>::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<Vertex*,VertexPositionComp> copy_vertex = _vertexes_to_route; // This is no more useful
// create a copy of _vertexes_to_route vector fo method UpdateEstimateCongestion
//set<Vertex*,VertexPositionComp> copy_vertex = _vertexes_to_route; // This is no more useful
//#if defined ( __USE_DYNAMIC_PRECONGESTION__ )
if ( !__ripupMode__ && (__precongestion__ == 2) )
UpdateEstimateCongestion();
//#endif
//#if defined ( __USE_DYNAMIC_PRECONGESTION__ )
if ( !__ripupMode__ && (__precongestion__ == 2) )
UpdateEstimateCongestion();
//#endif
//debugging = (dynamic_cast<DeepNet*>(_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, "<center><b>Dijkstra</b><br>initialized</center>");
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, "<center><b>Dijkstra</b><br>initialized</center>");
while ( _vertexes_to_route.size() > 1 ) {
// Now, let's expanse the top of the queue
VertexList reachedVertexes;
float reachedDistance = (float)(HUGE);
//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, "<center><b>Dijkstra</b><br>source connexe component</center>");
//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, "<center><b>Dijkstra</b><br>source connexe component</center>");
int oppositeConnex = oppositeVertex->getConnexID();
float oppositeDistance = oppositeVertex->getDistance();
if ( updateOppositeVertex or (newDistance + EPSILON < oppositeDistance) ) {
assert( oppositeConnex != firstVertexConnex );
oppositeVertex->setPredecessor( *iedge );
oppositeVertex->setDistance ( newDistance );
oppositeVertex->setNetStamp ( _netStamp );
VTuple* oppositeVTuple = oppositeVertex->getVTuple();
if (oppositeVTuple) {
ltrace(600) << "Increasing priority for:" << endl;
ltrace(600) << "* " << oppositeVertex << endl;
ltrace(600) << "* " << oppositeVTuple << endl;
increaseVTuplePriority( oppositeVTuple, newDistance );
// Du fait de la reinit ce n'est plus seulement un increase!
// Non, c'est bon si on garde le CleanRoutingState (avec clearPriorityQueue)
} else {
VTuple* newOppositeVTuple = VTuple::create ( oppositeVertex, newDistance );
ltrace(600) << "Creating New VTuple for Vertex:" << endl;
ltrace(600) << "* " << oppositeVertex << ":" << newDistance << endl;
ltrace(600) << "* " << newOppositeVTuple << endl;
addVTupleToPriorityQueue( newOppositeVTuple );
}
ltrace(600) << "Updated distance " << newDistance << " on: " << (*iedge) << endl;
printVTuplePriorityQueue();
//Breakpoint::stop(1, "<center><b>Dijkstra</b><br>distance has been updated</center>");
}
//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, "<center><b>Dijkstra</b><br>distance has been updated</center>");
}
//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<FTree> flutetree ( createFluteTree() );
@ -1986,25 +1974,29 @@ unsigned Graph::analyseRouting ( set<Segment*>& segmentsToUnroute )
}
}
}
unsigned nbDep = 0;
unsigned nbTot = 0;
float minimalCost = 0;
float maximalCost = 0;
for ( map<Segment*, segmentStat>::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<Segment*>& 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;

View File

@ -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 <QAction>
#include <QMenu>
#include <QMenuBar>
#include <hurricane/DebugSession.h>
#include <hurricane/Warning.h>
#include <hurricane/Go.h>
#include <hurricane/Cell.h>
@ -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()) );
}

View File

@ -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 <Christophe.Alexandre@lip6.fr>
// Hugo Cl<43>ment <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
//
// 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 <Damien.Dupuis@lip6.fr>
//
// 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 <climits>
#include <climits>
#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<Net*>(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:<br>&nbsp;&nbsp;<b>createGlobalGraph()</b>&nbsp;"
// "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<Segment*> &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<double> ( getCell(), "knikT", _timer.getCombTime () );
addMeasure<size_t> ( 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<Segment*>::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<RoutingLayerGauge*>::const_iterator ilayerGauge = rg->getLayerGauges().begin();
for ( ; ilayerGauge != rg->getLayerGauges().end() ; ++ilayerGauge ) {
vector<RoutingLayerGauge*>::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() ) {

View File

@ -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<Vertex*> 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 );

View File

@ -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

View File

@ -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; };

View File

@ -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 <math.h>
//#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<Vertex*>(_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<Vertex*>(_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
// *********

View File

@ -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<NetRecord> 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<NetRecord> NetVector;
// private: void RestructureNet ( Net* net );
// private: void createLimitedZone ( Net* net, set<Vertex*,VertexPositionComp> 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 ();

View File

@ -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;

View File

@ -46,7 +46,7 @@ namespace Knik {
public:
Vertex* getVertex() const { return _vertex; }
float getDistance() const { return _distance; }
string _getString() const { string s = "<VTuple: ";
string _getString() const { string s = "<VTuple d:";
s += getString(_distance);
if (_vertex) s += " " + getString(_vertex);
else s += " NULL";
@ -58,4 +58,7 @@ namespace Knik {
} // end namespace
GETSTRING_POINTER_SUPPORT(Knik::VTuple);
IOSTREAM_POINTER_SUPPORT(Knik::VTuple);
#endif

View File

@ -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 |

View File

@ -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,15 +11,9 @@
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./GraphicMaukaEngine.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
#include <functional>
#include <boost/bind.hpp>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
@ -42,6 +30,7 @@
#include <hurricane/viewer/CellWidget.h>
#include <hurricane/viewer/CellViewer.h>
#include <hurricane/viewer/ControllerWidget.h>
#include <hurricane/viewer/ExceptionWidget.h>
#include <crlcore/Utilities.h>
#include <crlcore/ToolBox.h>
#include <crlcore/AllianceFramework.h>
@ -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<ConfigurationWidget*>("controller.tabSettings.setting.mauka");

View File

@ -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 <string>
#include <boost/function.hpp>
#include <functional>
#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

View File

@ -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 <QObject>
@ -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

View File

@ -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

View File

@ -33,6 +33,8 @@
#ifdef HAVE_HMETIS_LIB
#include <climits>
#include "hurricane/Net.h"
#include "hurricane/Instance.h"
#include "hurricane/Plug.h"

View File

@ -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 <string>
#include <boost/function.hpp>
#include <functional>
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 (option<HMetisOptionsSize) _hmetisOptions[option] = value; }
} // End of Metis namespace.
} // Metis namespace.
INSPECTOR_P_SUPPORT(Metis::Configuration);
#endif // __METIS_CONFIGURATION__
#endif // METIS_CONFIGURATION_H

View File

@ -190,11 +190,11 @@ namespace Solstice {
SolsticeEngine* solstice = createEngine ( );
if ( !solstice ) return;
emit cellPreModificated ();
//emit cellPreModificated ();
solstice->compare ();
emit cellPostModificated ();
//emit cellPostModificated ();
_viewer->dumpObjectTree();
QTabWidget* ctrlTab = _viewer->getControllerWidget();
if (ctrlTab) {

View File

@ -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()

View File

@ -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 |

View File

@ -326,6 +326,7 @@ namespace Cfg {
;
}
def("hasParameter" , hasParameter );
def("getParamString" , getParamString1 , return_value_policy<reference_existing_object>());
def("getParamString" , getParamString2 , return_value_policy<reference_existing_object>());
def("getParamBool" , getParamBool1 , return_value_policy<reference_existing_object>());

View File

@ -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 <string>
#include <map>
@ -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="<undefined>" )
{
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