Anabatic transient commit 1.

* New: In Anabatic, basic support for GCell/Edge creation.
This commit is contained in:
Jean-Paul Chaput 2016-05-23 16:15:25 +02:00
parent f11be897ef
commit 61e9abddbd
25 changed files with 3191 additions and 1 deletions

39
anabatic/CMakeLists.txt Normal file
View File

@ -0,0 +1,39 @@
# -*- explicit-buffer-name: "CMakeLists.txt<anabatic>" -*-
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(ANABATIC)
option(BUILD_DOC "Build the documentation (doxygen)" OFF)
option(CHECK_DATABASE "Run database in full check mode (very slow)" OFF)
cmake_minimum_required(VERSION 2.8.9)
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
find_package(Bootstrap REQUIRED)
setup_project_paths(CORIOLIS)
set_cmake_policies()
set_lib_link_mode()
setup_boost()
setup_qt()
find_package(PythonLibs REQUIRED)
find_package(PythonSitePackages REQUIRED)
find_package(VLSISAPD REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)
add_subdirectory(src)
add_subdirectory(cmake_modules)
#if(BUILD_DOC)
# find_package(Doxygen)
# if(DOXYGEN_FOUND)
# add_subdirectory(doc)
# endif()
#endif()
if(CHECK_DATABASE)
add_definitions(-DCHECK_DATABASE)
message(STATUS "Checking database enabled (very slow).")
endif(CHECK_DATABASE)

View File

@ -0,0 +1 @@
install ( FILES FindANABATIC.cmake DESTINATION share/cmake/Modules )

View File

@ -0,0 +1,37 @@
# - Find the Katabatic includes and libraries.
# The following variables are set if Coriolis is found. If ANABATIC is not
# found, ANABATIC_FOUND is set to false.
# ANABATIC_FOUND - True when the Coriolis include directory is found.
# ANABATIC_INCLUDE_DIR - the path to where the Coriolis include files are.
# ANABATIC_LIBRARIES - The path to where the Coriolis library files are.
SET(ANABATIC_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis")
SET(ANABATIC_DIR_MESSAGE "Set the ANABATIC_INCLUDE_DIR cmake cache entry to the ${ANABATIC_INCLUDE_PATH_DESCRIPTION}")
# don't even bother under WIN32
IF(UNIX)
#
# Look for an installation.
#
FIND_PATH(ANABATIC_INCLUDE_PATH NAMES anabatic/AnabaticEngine.h PATHS
# Look in other places.
${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES include/coriolis
# Help the user find it if we cannot.
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
)
FIND_LIBRARY(ANABATIC_LIBRARY_PATH
NAMES anabatic
PATHS ${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES lib${LIB_SUFFIX}
# Help the user find it if we cannot.
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
)
SET_LIBRARIES_PATH(ANABATIC ANABATIC)
HURRICANE_CHECK_LIBRARIES(ANABATIC)
ENDIF(UNIX)

View File

@ -0,0 +1,138 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./AnabaticEngine.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include <iostream>
#include "hurricane/Error.h"
#include "hurricane/Cell.h"
#include "hurricane/UpdateSession.h"
#include "anabatic/GCell.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using std::cerr;
using std::cout;
using std::endl;
using std::ostringstream;
using Hurricane::Error;
using Hurricane::Cell;
using Hurricane::UpdateSession;
// -------------------------------------------------------------------
// Class : "Anabatic::AnabaticEngine".
Name AnabaticEngine::_toolName = "Anabatic";
AnabaticEngine* AnabaticEngine::get ( const Cell* cell )
{ return static_cast<AnabaticEngine*>(ToolEngine::get(cell,staticGetName())); }
const Name& AnabaticEngine::staticGetName ()
{ return _toolName; }
const Name& AnabaticEngine::getName () const
{ return _toolName; }
AnabaticEngine::AnabaticEngine ( Cell* cell )
: Super(cell)
, _configuration (new ConfigurationConcrete())
, _matrix ()
, _southWestGCell(NULL)
{
_matrix.setCell( cell, _configuration->getSliceHeight() );
}
void AnabaticEngine::_postCreate ()
{
Super::_postCreate();
//cdebug.setMinLevel(110);
//cdebug.setMaxLevel(120);
UpdateSession::open();
_southWestGCell = GCell::create( this );
UpdateSession::close();
}
AnabaticEngine* AnabaticEngine::create ( Cell* cell )
{
if (not cell) throw Error( "AnabaticEngine::create(): NULL cell argument." );
if (cell->getAbutmentBox().isEmpty())
throw Error( "AnabaticEngine::create(): %s has no abutment box." , getString(cell).c_str() );
AnabaticEngine* engine = new AnabaticEngine ( cell );
engine->_postCreate();
return engine;
}
AnabaticEngine::~AnabaticEngine ()
{
delete _configuration;
}
void AnabaticEngine::_preDestroy ()
{
// To be done: destroy the whole set of GCells.
// Must be stored in some way before destruction (in a set<> ?).
Super::_preDestroy();
}
Configuration* AnabaticEngine::getConfiguration ()
{ return _configuration; }
void AnabaticEngine::_runTest ()
{
cerr << "AnabaticEngine::_runTest() called." << endl;
}
string AnabaticEngine::_getTypeName () const
{ return getString(_toolName); }
string AnabaticEngine::_getString () const
{
ostringstream os;
os << "<" << _toolName << " " << _cell->getName() << ">";
return os.str();
}
Record* AnabaticEngine::_getRecord () const
{
Record* record = Super::_getRecord();
record->add( getSlot("_configuration" , _configuration ) );
record->add( getSlot("_southWestGCell", _southWestGCell) );
record->add( getSlot("_matrix" , &_matrix ) );
return record;
}
} // Anabatic namespace.

View File

@ -0,0 +1,72 @@
# -*- explicit-buffer-name: "CMakeLists.txt<anabatic/src>" -*-
if ( CHECK_DETERMINISM )
add_definitions ( -DCHECK_DETERMINISM )
endif ( CHECK_DETERMINISM )
include_directories( ${ANABATIC_SOURCE_DIR}/src
${CORIOLIS_INCLUDE_DIR}
${HURRICANE_INCLUDE_DIR}
${CONFIGURATION_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${QtX_INCLUDE_DIR}
${PYTHON_INCLUDE_PATH}
)
set( includes anabatic/Constants.h
anabatic/Configuration.h
anabatic/Matrix.h
anabatic/Edge.h
anabatic/GCell.h #anabatic/GCells.h
anabatic/AnabaticEngine.h
anabatic/GraphicAnabaticEngine.h
)
set( mocIncludes anabatic/GraphicAnabaticEngine.h )
set( pyIncludes anabatic/PyAnabaticEngine.h
anabatic/PyGraphicAnabaticEngine.h
)
set( cpps Constants.cpp
Configuration.cpp
Matrix.cpp
Edge.cpp
GCell.cpp
AnabaticEngine.cpp
GraphicAnabaticEngine.cpp
)
set( pyCpps PyAnabaticEngine.cpp
PyGraphicAnabaticEngine.cpp
PyAnabatic.cpp
)
qtX_wrap_cpp( mocCpps ${mocIncludes} )
set( depLibs ${CORIOLIS_PYTHON_LIBRARIES}
${CORIOLIS_LIBRARIES}
${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
${HURRICANE_LIBRARIES}
${CONFIGURATION_LIBRARY}
${CIF_LIBRARY}
${AGDS_LIBRARY}
${LEFDEF_LIBRARIES}
${OA_LIBRARIES}
${QtX_LIBRARIES}
${Boost_LIBRARIES}
${LIBXML2_LIBRARIES}
${PYTHON_LIBRARIES} -lutil
)
add_library( anabatic ${cpps} ${mocCpps} )
set_target_properties( anabatic PROPERTIES VERSION 1.0 SOVERSION 1 )
target_link_libraries( anabatic ${depLibs} )
add_python_module( "${pyCpps}"
"${pyIncludes}"
"pyanabatic;1.0;1"
Anabatic
"anabatic;${depLibs}"
include/coriolis2/anabatic
)
install( TARGETS anabatic DESTINATION lib${LIB_SUFFIX} )
install( FILES ${includes}
${mocIncludes} DESTINATION include/coriolis2/anabatic )

View File

@ -0,0 +1,312 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | 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/RegularLayer.h"
#include "hurricane/Cell.h"
#include "crlcore/Utilities.h"
#include "crlcore/CellGauge.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/RoutingLayerGauge.h"
#include "crlcore/AllianceFramework.h"
#include "anabatic/Configuration.h"
namespace Anabatic {
using std::cout;
using std::cerr;
using std::endl;
using std::setprecision;
using std::ostringstream;
using std::vector;
using Hurricane::tab;
using Hurricane::Warning;
using Hurricane::Error;
using Hurricane::Technology;
using Hurricane::DataBase;
using Hurricane::RegularLayer;
using CRL::AllianceFramework;
using CRL::RoutingGauge;
using CRL::RoutingLayerGauge;
// -------------------------------------------------------------------
// Class : "Anabatic::Configuration".
Configuration::Configuration () { }
Configuration::~Configuration () { }
// -------------------------------------------------------------------
// Class : "Anabatic::ConfigurationConcrete".
ConfigurationConcrete::ConfigurationConcrete ( const CellGauge* cg, const RoutingGauge* rg )
: Configuration ()
, _cg (NULL)
, _rg (NULL)
, _extensionCaps ()
, _allowedDepth (0)
{
if (cg == NULL) cg = AllianceFramework::get()->getCellGauge();
if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge();
_cg = cg->getClone();
_rg = rg->getClone();
if (Cfg::hasParameter("anabatic.topRoutingLayer")) {
_setTopRoutingLayer( Cfg::getParamString("anabatic.topRoutingLayer")->asString() );
} else
_allowedDepth = rg->getDepth()-1;
_gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh");
_gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv");
_gcontact = DataBase::getDB()->getTechnology()->getLayer("gcontact");
if (_gcontact == NULL) cerr << Warning("Cannot get \"gcontact\" layer from the Technology.") << endl;
if (_gmetalv == NULL) cerr << Warning("Cannot get \"gmetalv\" layer from the Technology.") << endl;
if (_gmetalh == NULL) cerr << Warning("Cannot get \"gmetalh\" layer from the Technology.") << endl;
//DbU::Unit sliceHeight = _cg->getSliceHeight();
const vector<RoutingLayerGauge*>& layerGauges = rg->getLayerGauges();
for ( size_t depth=0 ; depth < layerGauges.size() ; ++depth ) {
const RegularLayer* regularLayer = dynamic_cast<const RegularLayer*>( layerGauges[depth]->getLayer() );
if (regularLayer)
_extensionCaps.push_back( regularLayer->getExtentionCap() );
else {
_extensionCaps.push_back( 0 );
cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n"
" (%s)"
, depth
, getString(layerGauges[depth]->getLayer()).c_str()
) << endl;
}
}
}
ConfigurationConcrete::ConfigurationConcrete ( const ConfigurationConcrete& other )
: Configuration()
, _gmetalh (other._gmetalh)
, _gmetalv (other._gmetalv)
, _gcontact (other._gcontact)
, _cg (NULL)
, _rg (NULL)
, _extensionCaps (other._extensionCaps)
, _allowedDepth (other._allowedDepth)
{
if (other._cg) _cg = other._cg->getClone();
if (other._rg) _rg = other._rg->getClone();
}
ConfigurationConcrete::~ConfigurationConcrete ()
{
cdebug.log(145) << "About to delete attribute _rg (RoutingGauge)." << endl;
_cg->destroy ();
_rg->destroy ();
}
ConfigurationConcrete* ConfigurationConcrete::clone () const
{ return new ConfigurationConcrete(*this); }
bool ConfigurationConcrete::isGMetal ( const Layer* layer ) const
{ return (layer and ((layer == _gmetalh) or (layer == _gmetalv))); }
bool ConfigurationConcrete::isGContact ( const Layer* layer ) const
{ return (layer and (layer == _gcontact)); }
size_t ConfigurationConcrete::getDepth () const
{ return _rg->getDepth(); }
size_t ConfigurationConcrete::getAllowedDepth () const
{ return _allowedDepth; }
size_t ConfigurationConcrete::getLayerDepth ( const Layer* layer ) const
{ return _rg->getLayerDepth(layer); }
CellGauge* ConfigurationConcrete::getCellGauge () const
{ return _cg; }
RoutingGauge* ConfigurationConcrete::getRoutingGauge () const
{ return _rg; }
RoutingLayerGauge* ConfigurationConcrete::getLayerGauge ( size_t depth ) const
{ return _rg->getLayerGauge(depth); }
const Layer* ConfigurationConcrete::getRoutingLayer ( size_t depth ) const
{ return _rg->getRoutingLayer(depth); }
Layer* ConfigurationConcrete::getContactLayer ( size_t depth ) const
{ return _rg->getContactLayer(depth); }
DbU::Unit ConfigurationConcrete::getSliceHeight () const
{ return _cg->getSliceHeight(); }
DbU::Unit ConfigurationConcrete::getSliceStep () const
{ return _cg->getSliceStep(); }
DbU::Unit ConfigurationConcrete::getPitch ( const Layer* layer, Flags flags ) const
{ return getPitch( getLayerDepth(layer), flags ); }
DbU::Unit ConfigurationConcrete::getOffset ( const Layer* layer ) const
{ return getOffset( getLayerDepth(layer) ); }
DbU::Unit ConfigurationConcrete::getExtensionCap ( const Layer* layer ) const
{ return getExtensionCap( getLayerDepth(layer) ); }
DbU::Unit ConfigurationConcrete::getWireWidth ( const Layer* layer ) const
{ return getWireWidth( getLayerDepth(layer) ); }
Flags ConfigurationConcrete::getDirection ( const Layer* layer ) const
{ return getDirection( getLayerDepth(layer) ); }
DbU::Unit ConfigurationConcrete::getPitch ( size_t depth, Flags flags ) const
{
if (flags == Flags::NoFlags) return _rg->getLayerPitch(depth);
if (flags & Flags::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 & Flags::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); }
DbU::Unit ConfigurationConcrete::getExtensionCap ( size_t depth ) const
{ return _extensionCaps[depth]; }
Flags ConfigurationConcrete::getDirection ( size_t depth ) const
{ return _rg->getLayerDirection(depth); }
void ConfigurationConcrete::setAllowedDepth ( size_t allowedDepth )
{ _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::print ( Cell* cell ) const
{
string topLayerName = "UNKOWN";
const Layer* topLayer = _rg->getRoutingLayer( _allowedDepth );
if (topLayer)
topLayerName = getString( topLayer->getName() );
cout << " o Configuration of ToolEngine<Anabatic> for Cell <" << cell->getName() << ">" << endl;
cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl;
cout << Dots::asString (" - Top routing layer" ,topLayerName) << endl;
}
string ConfigurationConcrete::_getTypeName () const
{
return "ConfigurationConcrete";
}
string ConfigurationConcrete::_getString () const
{
ostringstream os;
os << "<" << _getTypeName() << " " << _rg->getName() << ">";
return os.str();
}
Record* ConfigurationConcrete::_getRecord () const
{
Record* record = new Record ( _getString() );
record->add ( getSlot( "_rg" , _rg ) );
record->add ( getSlot( "_gmetalh" , _gmetalh ) );
record->add ( getSlot( "_gmetalv" , _gmetalv ) );
record->add ( getSlot( "_gcontact" , _gcontact ) );
record->add ( getSlot( "_allowedDepth" , _allowedDepth ) );
return ( record );
}
} // Anabatic namespace.

View File

@ -0,0 +1,50 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Constants.cpp" |
// +-----------------------------------------------------------------+
#include <string>
#include "anabatic/Constants.h"
namespace Anabatic {
using std::string;
Flags::~Flags ()
{ }
string Flags::_getTypeName () const
{ return "Anabatic::Flags"; }
string Flags::_getString () const
{
string s = "";
s += (_flags & Horizontal ) ? 'h' : '-';
s += (_flags & Vertical ) ? 'v' : '-';
s += (_flags & SourceGCell) ? 's' : '-';
s += (_flags & TargetGCell) ? 't' : '-';
s += (_flags & Invalidated) ? 'i' : '-';
s += (_flags & MoveSide ) ? 'M' : '-';
s += (_flags & PitchAbove ) ? 'A' : '-';
s += (_flags & PitchBelow ) ? 'B' : '-';
return s;
}
} // Anabatic namespace.

238
anabatic/src/Edge.cpp Normal file
View File

@ -0,0 +1,238 @@
// -*- mode: C++; explicit-buffer-name: "Edge.cpp<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Edge.cpp" |
// +-----------------------------------------------------------------+
#include <iostream>
#include "hurricane/Error.h"
#include "anabatic/Edge.h"
#include "anabatic/GCell.h"
namespace Anabatic {
using std::cerr;
using std::endl;
using Hurricane::Error;
Name Edge::_extensionName = "Anabatic::Edge";
Edge::Edge ( GCell* source, GCell* target, Flags flags )
: Super(source->getCell())
, _flags (flags|Flags::Invalidated)
, _capacity (0)
, _realOccupancy (0)
, _estimateOccupancy(0.0)
, _source (source)
, _target (target)
, _axis (0)
{ }
void Edge::_postCreate ()
{
Super::_postCreate();
if (_flags.isset(Flags::Horizontal)) {
_axis = std::max( _source->getYMin(), _target->getYMin() );
_source->_add( this, Flags::EastSide );
_target->_add( this, Flags::WestSide );
} else {
_axis = std::max( _source->getXMin(), _target->getXMin() );
_source->_add( this, Flags::NorthSide );
_target->_add( this, Flags::SouthSide );
}
}
Edge* Edge::create ( GCell* source, GCell* target, Flags flags )
{
if (not source) throw Error( "Edge::create(): NULL source argument." );
if (not target) throw Error( "Edge::create(): NULL target argument." );
if (source == target)
throw Error("Edge::create(): Source & target are the same (%s).", getString(source).c_str() );
if (not (flags.intersect(Flags::Horizontal|Flags::Vertical))) {
Box border = GCell::getBorder( source, target );
if (border.isEmpty())
throw Error( "Edge::create(): source & target GCells are *not* contiguous.\n"
" source:%s\n"
" target:%s"
, getString(source).c_str()
, getString(target).c_str()
);
if (border.getYMin() == border.getYMax()) flags |= Flags::Horizontal;
else flags |= Flags::Vertical;
}
Edge* edge = new Edge ( source, target, flags );
edge->_postCreate();
cdebug.log(110,1) << "Edge::create(): " << (void*)edge << ":" << edge << endl;
cdebug.log(110) << "source:" << edge->getSource() << endl;
cdebug.log(110) << "target:" << edge->getTarget() << endl;
cdebug.tabw(110,-1);
return edge;
}
Edge::~Edge ()
{ }
void Edge::_preDestroy ()
{
_source->_remove( this, _flags|Flags::SourceGCell );
_target->_remove( this, _flags|Flags::TargetGCell );
Super::_preDestroy();
}
void Edge::destroy ()
{
_preDestroy();
delete this;
}
DbU::Unit Edge::getAxisMin () const
{
if (_flags.isset(Flags::Vertical))
return std::max( _source->getXMin(), _target->getXMin() );
return std::max( _source->getYMin(), _target->getYMin() );
}
GCell* Edge::getOpposite ( const GCell* from ) const
{
if (from == _source) return _target;
if (from == _target) return _source;
cerr << Error( "Edge::getOpposite(): On %s,\n"
" \"from\" CGell id:%u is neither source nor target (S-id:%u, T-id:%u)."
, getString(this).c_str()
, from->getId()
, _source->getId()
, _target->getId()
) << endl;
return NULL;
}
Interval Edge::getSide () const
{
Interval side;
if (_flags.isset(Flags::Vertical))
side = Interval( std::max(_source->getXMin(),_target->getXMin())
, std::min(_source->getXMax(),_target->getXMax()) );
else
side = Interval( std::max(_source->getYMin(),_target->getYMin())
, std::min(_source->getYMax(),_target->getYMax()) );
return side;
}
void Edge::_setSource ( GCell* source )
{
if (source == _target)
throw Error("Edge::_setSource(): Source & target are the same (%s).", getString(source).c_str() );
invalidate(); _source=source;
}
void Edge::_setTarget ( GCell* target )
{
if (_source == target)
throw Error("Edge::_setTarget(): Source & target are the same (%s).", getString(target).c_str() );
invalidate(); _target=target;
}
void Edge::_revalidate ()
{
_axis = getSide().getCenter();
_flags.reset( Flags::Invalidated );
cdebug.log(110) << "Edge::_revalidate() " << this << endl;
}
const Name& Edge::getName () const
{ return _extensionName; }
Box Edge::getBoundingBox () const
{
static DbU::Unit halfThickness = DbU::fromLambda( 2.0 );
static DbU::Unit halfLength = DbU::fromLambda( 12.0 );
if (_flags.isset(Flags::Horizontal))
return Box( _target->getXMin() - halfLength, _axis - halfThickness
, _target->getXMin() + halfLength, _axis + halfThickness
);
return Box( _axis - halfThickness, _target->getYMin() - halfLength
, _axis + halfThickness, _target->getYMin() + halfLength
);
}
void Edge::translate ( const DbU::Unit&, const DbU::Unit& )
{
cerr << Error( "Edge::translate(): On %s,\n"
" Must never be called on a Edge object (ignored)."
, getString(this).c_str()
) << endl;
}
string Edge::_getTypeName () const
{ return getString(_extensionName); }
string Edge::_getString () const
{
string s = Super::_getString();
s.insert( s.size()-1, " "+DbU::getValueString(_axis) );
s.insert( s.size()-1, " "+getString(_realOccupancy) );
s.insert( s.size()-1, "/"+getString(_capacity) );
s.insert( s.size()-1, " "+getString(_flags) );
return s;
}
Record* Edge::_getRecord () const
{
Record* record = Super::_getRecord();
record->add( getSlot("_flags" , _flags ) );
record->add( getSlot("_capacity" , _capacity ) );
record->add( getSlot("_realOccupancy" , _realOccupancy ) );
record->add( getSlot("_estimateOccupancy", _estimateOccupancy) );
record->add( getSlot("_source" , _source ) );
record->add( getSlot("_target" , _target ) );
record->add( DbU::getValueSlot("_axis", &_axis) );
return record;
}
} // Anabatic namespace.

490
anabatic/src/GCell.cpp Normal file
View File

@ -0,0 +1,490 @@
// -*- mode: C++; explicit-buffer-name: "GCell.cpp<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./GCell.cpp" |
// +-----------------------------------------------------------------+
#include <iostream>
#include "anabatic/GCell.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using std::cerr;
using std::endl;
using Hurricane::Error;
Name GCell::_extensionName = "Anabatic::GCell";
GCell::GCell ( AnabaticEngine* anabatic, DbU::Unit xmin, DbU::Unit ymin )
: Super(anabatic->getCell())
, _anabatic (anabatic)
, _flags (Flags::NoFlags)
, _westEdges ()
, _eastEdges ()
, _southEdges()
, _northEdges()
, _xmin (xmin)
, _ymin (ymin)
{ }
void GCell::_postCreate ()
{
Super::_postCreate();
}
GCell* GCell::create ( AnabaticEngine* anabatic )
{
if (not anabatic) throw Error( "GCell::create(): NULL anabatic argument." );
if (not anabatic->getCell()) throw Error( "GCell::create(): AnabaticEngine has no Cell loaded." );
GCell* gcell = new GCell ( anabatic
, anabatic->getCell()->getAbutmentBox().getXMin()
, anabatic->getCell()->getAbutmentBox().getYMin() );
gcell->_postCreate();
gcell->_revalidate();
return gcell;
}
GCell* GCell::_create ( DbU::Unit xmin, DbU::Unit ymin )
{
GCell* gcell = new GCell ( getAnabatic(), xmin, ymin );
gcell->_postCreate();
return gcell;
}
GCell::~GCell ()
{ }
void GCell::_preDestroy ()
{
for ( Edge* edge : _westEdges ) edge->destroy();
for ( Edge* edge : _eastEdges ) edge->destroy();
for ( Edge* edge : _southEdges ) edge->destroy();
for ( Edge* edge : _northEdges ) edge->destroy();
Super::_preDestroy();
}
void GCell::destroy ()
{
_preDestroy();
delete this;
}
void GCell::_remove ( Edge* edge, Flags side )
{
if (side.contains(Flags::WestSide )) erase_element( _westEdges, edge );
if (side.contains(Flags::EastSide )) erase_element( _eastEdges, edge );
if (side.contains(Flags::SouthSide)) erase_element( _southEdges, edge );
if (side.contains(Flags::NorthSide)) erase_element( _northEdges, edge );
}
void GCell::_add ( Edge* edge, Flags side )
{
cdebug.log(110,1) << "GCell::_add(side): side:" << side << " " << edge << endl;
if (side.contains(Flags::WestSide)) {
cdebug.log(110) << "Adding to West side of " << this << endl;
for ( auto iedge=_westEdges.begin() ; iedge != _westEdges.end() ; ++iedge )
if ((*iedge)->getAxisMin() >= edge->getAxisMin()) {
_westEdges.insert( iedge, edge );
cdebug.tabw(110,-1);
return;
}
_westEdges.push_back( edge );
}
if (side.contains(Flags::EastSide)) {
cdebug.log(110) << "Adding to East side of " << this << endl;
for ( auto iedge=_eastEdges.begin() ; iedge != _eastEdges.end() ; ++iedge )
if ((*iedge)->getAxisMin() >= edge->getAxisMin()) {
_eastEdges.insert( iedge, edge );
cdebug.tabw(110,-1);
return;
}
_eastEdges.push_back( edge );
}
if (side.contains(Flags::SouthSide)) {
cdebug.log(110) << "Adding to South side of " << this << endl;
for ( auto iedge=_southEdges.begin() ; iedge != _southEdges.end() ; ++iedge )
cdebug.log(110) << "| @" << DbU::getValueString((*iedge)->getAxisMin()) << " " << *iedge << endl;
for ( auto iedge=_southEdges.begin() ; iedge != _southEdges.end() ; ++iedge )
if ((*iedge)->getAxisMin() >= edge->getAxisMin()) {
cdebug.log(110) << "Insert *before* " << *iedge << endl;
_southEdges.insert( iedge, edge );
for ( auto iedge2=_southEdges.begin() ; iedge2 != _southEdges.end() ; ++iedge2 )
cdebug.log(110) << "| @" << DbU::getValueString((*iedge)->getAxisMin()) << " " << *iedge2 << endl;
cdebug.tabw(110,-1);
return;
}
_southEdges.push_back( edge );
}
if (side.contains(Flags::NorthSide)) {
cdebug.log(110) << "Adding to North side of " << this << endl;
for ( auto iedge=_northEdges.begin() ; iedge != _northEdges.end() ; ++iedge )
if ((*iedge)->getAxisMin() >= edge->getAxisMin()) {
_northEdges.insert( iedge, edge );
cdebug.tabw(110,-1);
return;
}
_northEdges.push_back( edge );
}
cdebug.tabw(110,-1);
}
Box GCell::getBorder ( const GCell* s, const GCell* t )
{
Flags flags = Flags::NoFlags;
flags |= (s->getXMax() == t->getXMin()) ? Flags::EastSide : 0;
flags |= (t->getXMax() == s->getXMin()) ? Flags::WestSide : 0;
flags |= (s->getYMax() == t->getYMin()) ? Flags::NorthSide : 0;
flags |= (t->getYMax() == s->getYMin()) ? Flags::SouthSide : 0;
if (flags & Flags::Vertical) {
if (flags & Flags::Horizontal) return Box();
if (flags & Flags::WestSide)
return Box( s->getXMin(), std::max( s->getYMin(), t->getYMin() )
, s->getXMin(), std::min( s->getYMax(), t->getYMax() ) );
else
return Box( t->getXMin(), std::max( s->getYMin(), t->getYMin() )
, t->getXMin(), std::min( s->getYMax(), t->getYMax() ) );
}
if (flags & Flags::Horizontal) {
if (flags & Flags::Vertical) return Box();
if (flags & Flags::NorthSide)
return Box( std::max( s->getXMin(), t->getXMin() ), t->getYMin()
, std::min( s->getXMax(), t->getXMax() ), t->getYMin() );
else
return Box( std::max( s->getXMin(), t->getXMin() ), s->getYMin()
, std::min( s->getXMax(), t->getXMax() ), s->getYMin() );
}
return Box();
}
GCell* GCell::vcut ( DbU::Unit x )
{
cdebug.log(110,1) << "GCell::vcut() @x:" << DbU::getValueString(x) << " " << this << endl;
if ( (x < getXMin()) or (x > getXMax()) )
throw Error( "GCell::vcut(): Vertical cut axis at %s is outside GCell box,\n"
" in %s."
, DbU::getValueString(x).c_str()
, getString(this).c_str()
);
GCell* chunk = _create( x, getYMin() );
_moveEdges( chunk, 0, Flags::EastSide|Flags::MoveSide );
Edge::create( this, chunk, Flags::Horizontal );
if (not _southEdges.empty()) {
cdebug.log(110) << "Split/create south edges." << endl;
size_t iedge = 0;
for ( ; (iedge < _southEdges.size()) ; ++iedge ) {
cdebug.log(110) << "[" << iedge << "] xmax of:"
<< _southEdges[iedge]->getOpposite(this)
<< " " << _southEdges[iedge] << endl;
if (x <= _southEdges[iedge]->getOpposite(this)->getXMax()) break;
}
if (x < _southEdges[iedge]->getOpposite(this)->getXMax())
Edge::create( _southEdges[iedge]->getOpposite(this), chunk, Flags::Vertical );
_moveEdges( chunk, iedge+1, Flags::SouthSide );
}
if (not _northEdges.empty()) {
cdebug.log(110) << "Split/create north edges." << endl;
size_t iedge = 0;
for ( ; (iedge < _northEdges.size()) ; ++iedge )
if (x <= _northEdges[iedge]->getOpposite(this)->getXMax()) break;
if (x < _northEdges[iedge]->getOpposite(this)->getXMax())
Edge::create( chunk, _northEdges[iedge]->getOpposite(this), Flags::Vertical );
_moveEdges( chunk, iedge+1, Flags::NorthSide );
}
_revalidate();
chunk->_revalidate();
cdebug.tabw(110,-1);
return chunk;
}
GCell* GCell::hcut ( DbU::Unit y )
{
cdebug.log(110,1) << "GCell::hcut() @y:" << DbU::getValueString(y) << " " << this << endl;
if ( (y < getYMin()) or (y > getYMax()) )
throw Error( "GCell::hcut(): Horizontal cut axis at %s is outside GCell box,\n"
" in %s."
, DbU::getValueString(y).c_str()
, getString(this).c_str()
);
GCell* chunk = _create( getXMin(), y );
_moveEdges( chunk, 0, Flags::NorthSide|Flags::MoveSide );
Edge::create( this, chunk, Flags::Vertical );
if (not _westEdges.empty()) {
size_t iedge = 0;
for ( ; (iedge < _westEdges.size()) ; ++iedge )
if (y <= _westEdges[iedge]->getOpposite(this)->getYMax()) break;
if (y < _westEdges[iedge]->getOpposite(this)->getYMax())
Edge::create( _westEdges[iedge]->getOpposite(this), chunk, Flags::Horizontal );
_moveEdges( chunk, iedge+1, Flags::WestSide );
}
if (not _eastEdges.empty()) {
size_t iedge = 0;
for ( ; (iedge < _eastEdges.size()) ; ++iedge )
if (y <= _eastEdges[iedge]->getOpposite(this)->getYMax()) break;
if (y < _eastEdges[iedge]->getOpposite(this)->getYMax())
Edge::create( chunk, _eastEdges[iedge]->getOpposite(this), Flags::Horizontal );
_moveEdges( chunk, iedge+1, Flags::EastSide );
}
_revalidate();
chunk->_revalidate();
cdebug.tabw(110,-1);
return chunk;
}
bool GCell::doGrid ()
{
DbU::Unit side = getAnabatic()->getConfiguration()->getSliceHeight();
Interval hspan = getSide( Flags::Horizontal );
Interval vspan = getSide( Flags::Vertical );
if (hspan.getSize() < 3*side) {
cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
" (%s)"
, DbU::getValueString(hspan.getSize()).c_str()
, getString(this).c_str()
) << endl;
return false;
}
if (vspan.getSize() < 3*side) {
cerr << Error( "GCell::doGrid(): GCell is too narrow (dy:%s) to build a grid.\n"
" (%s)"
, DbU::getValueString(vspan.getSize()).c_str()
, getString(this).c_str()
) << endl;
return false;
}
GCell* row = this;
GCell* column = NULL;
DbU::Unit ycut = vspan.getVMin()+side;
for ( ; ycut < vspan.getVMax() ; ycut += side ) {
column = row;
row = row->hcut( ycut );
for ( DbU::Unit xcut = hspan.getVMin()+side ; xcut < hspan.getVMax() ; xcut += side ) {
column = column->vcut( xcut );
}
}
column = row;
for ( DbU::Unit xcut = hspan.getVMin()+side ; xcut < hspan.getVMax() ; xcut += side ) {
column = column->vcut( xcut );
}
return true;
}
void GCell::_revalidate ()
{
cdebug.log(110,1) << "GCell::revalidate() " << this << endl;
cdebug.log(110,1) << "West side." << endl; for ( Edge* edge : _westEdges ) edge->revalidate(); cdebug.tabw(110,-1);
cdebug.log(110,1) << "East side." << endl; for ( Edge* edge : _eastEdges ) edge->revalidate(); cdebug.tabw(110,-1);
cdebug.log(110,1) << "South side." << endl; for ( Edge* edge : _southEdges ) edge->revalidate(); cdebug.tabw(110,-1);
cdebug.log(110,1) << "North side." << endl; for ( Edge* edge : _northEdges ) edge->revalidate(); cdebug.tabw(110,-1);
_anabatic->_updateLookup( this );
cdebug.tabw(110,-1);
}
void GCell::_moveEdges ( GCell* dest, size_t ibegin, Flags flags )
{
cdebug.log(110,1) << "GCell::_moveEdges() " << this << endl;
cdebug.log(110) << " toward " << dest << endl;
cdebug.log(110) << " ibegin: " << ibegin << " flags:" << flags << endl;
size_t iclear = ibegin;
if (flags.contains(Flags::SouthSide) and not _southEdges.empty()) {
cdebug.log(110) << "South side." << endl;
if (iclear < _southEdges.size()) {
for ( size_t iedge=ibegin ; (iedge < _southEdges.size()) ; ++iedge ) {
if (flags & Flags::MoveSide) _southEdges[iedge]->_setSource( dest );
else _southEdges[iedge]->_setTarget( dest );
dest->_southEdges.push_back( _southEdges[iedge] );
}
_southEdges.resize( iclear );
} else {
if (iclear > _southEdges.size())
cerr << Error("GCell::_moveEdges(): On south side, iclear=%u is greater than size()-1=%u\n"
" (%s)"
, iclear
, _southEdges.size()
, getString(this).c_str()
) << endl;
}
}
if (flags.contains(Flags::NorthSide) and not _northEdges.empty()) {
cdebug.log(110) << "North side." << endl;
if (iclear < _northEdges.size()) {
for ( size_t iedge=ibegin ; (iedge < _northEdges.size()) ; ++iedge ) {
if (flags & Flags::MoveSide) _northEdges[iedge]->_setTarget( dest );
else _northEdges[iedge]->_setSource( dest );
dest->_northEdges.push_back( _northEdges[iedge] );
}
_northEdges.resize( iclear );
} else {
if (iclear > _northEdges.size())
cerr << Error("GCell::_moveEdges(): On north side, iclear=%u is greater than size()-1=%u\n"
" (%s)"
, iclear
, _northEdges.size()
, getString(this).c_str()
) << endl;
}
}
if (flags.contains(Flags::WestSide) and not _westEdges.empty()) {
cdebug.log(110) << "West side." << endl;
if (iclear < _westEdges.size()) {
for ( size_t iedge=ibegin ; (iedge < _westEdges.size()) ; ++iedge ) {
if (flags & Flags::MoveSide) _westEdges[iedge]->_setSource( dest );
else _westEdges[iedge]->_setTarget( dest );
dest->_westEdges.push_back( _westEdges[iedge] );
}
_westEdges.resize( iclear );
} else {
if (iclear > _westEdges.size())
cerr << Error("GCell::_moveEdges(): On west side, iclear=%u is greater than size()-1=%u\n"
" (%s)"
, iclear
, _westEdges.size()
, getString(this).c_str()
) << endl;
}
}
if (flags.contains(Flags::EastSide) and not _eastEdges.empty()) {
cdebug.log(110) << "East side." << endl;
if (iclear < _eastEdges.size()) {
for ( size_t iedge=ibegin ; (iedge < _eastEdges.size()) ; ++iedge ) {
if (flags & Flags::MoveSide) _eastEdges[iedge]->_setTarget( dest );
else _eastEdges[iedge]->_setSource( dest );
dest->_eastEdges.push_back( _eastEdges[iedge] );
}
_eastEdges.resize( iclear );
} else {
if (iclear > _eastEdges.size())
cerr << Error("GCell::_moveEdges(): On east side, iclear=%u is greater than size()-1=%u\n"
" (%s)"
, iclear
, _eastEdges.size()
, getString(this).c_str()
) << endl;
}
}
cdebug.tabw(110,-1);
}
const Name& GCell::getName () const
{ return _extensionName; }
Box GCell::getBoundingBox () const
{
return Box( getXMin(), getYMin(), getXMax(), getYMax() );
}
void GCell::translate ( const DbU::Unit&, const DbU::Unit& )
{
cerr << Error( "GCell::translate(): On %s,\n"
" Must never be called on a GCell object (ignored)."
, getString(this).c_str()
) << endl;
}
string GCell::_getTypeName () const
{ return getString(_extensionName); }
string GCell::_getString () const
{
string s = Super::_getString();
s.insert( s.size()-1, " "+getString(getBoundingBox()) );
s.insert( s.size()-1, " "+getString(_flags) );
return s;
}
Record* GCell::_getRecord () const
{
Record* record = Super::_getRecord();
record->add( getSlot("_flags" , &_flags ) );
record->add( getSlot("_westEdges" , &_westEdges ) );
record->add( getSlot("_eastEdges" , &_eastEdges ) );
record->add( getSlot("_southEdges", &_southEdges) );
record->add( getSlot("_northEdges", &_northEdges) );
record->add( DbU::getValueSlot("_xmin", &_xmin) );
record->add( DbU::getValueSlot("_ymin", &_ymin) );
return record;
}
} // Anabatic namespace.

View File

@ -0,0 +1,286 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "GraphicAnabaticEngine.cpp" |
// +-----------------------------------------------------------------+
#include <boost/bind.hpp>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QApplication>
#include <hurricane/Warning.h>
#include <hurricane/Error.h>
#include <hurricane/Breakpoint.h>
#include <hurricane/DebugSession.h>
#include <hurricane/Go.h>
#include <hurricane/Net.h>
#include <hurricane/Cell.h>
#include <hurricane/viewer/Graphics.h>
#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 "anabatic/GCell.h"
#include "anabatic/GraphicAnabaticEngine.h"
namespace Anabatic {
using namespace std;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Exception;
using Hurricane::Breakpoint;
using Hurricane::DebugSession;
using Hurricane::Point;
using Hurricane::Entity;
using Hurricane::Net;
using Hurricane::Graphics;
using Hurricane::ColorScale;
using Hurricane::DisplayStyle;
using Hurricane::ControllerWidget;
using Hurricane::ExceptionWidget;
using CRL::Catalog;
using CRL::AllianceFramework;
size_t GraphicAnabaticEngine::_references = 0;
GraphicAnabaticEngine* GraphicAnabaticEngine::_singleton = NULL;
void GraphicAnabaticEngine::initGCell ( CellWidget* widget )
{
widget->getDrawingPlanes().setPen( Qt::NoPen );
}
void GraphicAnabaticEngine::drawGCell ( CellWidget* widget
, const Go* go
, const BasicLayer* basicLayer
, const Box& box
, const Transformation& transformation
)
{
const GCell* gcell = static_cast<const GCell*>(go);
QPainter& painter = widget->getPainter();
painter.setPen ( Graphics::getPen ("gcell",widget->getDarkening()) );
painter.setBrush( Graphics::getBrush("gcell",widget->getDarkening()) );
painter.drawRect( widget->dbuToScreenRect(gcell->getBoundingBox()) );
}
void GraphicAnabaticEngine::initEdge ( CellWidget* widget )
{
widget->getDrawingPlanes().setPen( Qt::NoPen );
}
void GraphicAnabaticEngine::drawEdge ( CellWidget* widget
, const Go* go
, const BasicLayer* basicLayer
, const Box& box
, const Transformation& transformation
)
{
const Edge* edge = static_cast<const Edge*>(go);
if (edge) {
unsigned int occupancy = 255;
if (edge->getRealOccupancy() < edge->getCapacity())
occupancy = (unsigned int)( 255.0 * ( (float)edge->getRealOccupancy() / (float)edge->getCapacity() ) );
QPainter& painter = widget->getPainter();
if (edge->getRealOccupancy() > edge->getCapacity()) {
QColor color ( Qt::cyan );
painter.setPen( DisplayStyle::darken(color,widget->getDarkening()) );
}
QBrush brush = QBrush( Qt::white, Qt::DiagCrossPattern );
if (edge->getCapacity() > 0.0)
brush = Graphics::getColorScale( ColorScale::Fire ).getBrush( occupancy, widget->getDarkening() );
painter.setPen( Qt::NoPen );
painter.setBrush( brush );
painter.drawRect( widget->dbuToScreenRect(edge->getBoundingBox(), false) );
}
}
AnabaticEngine* GraphicAnabaticEngine::createEngine ()
{
Cell* cell = getCell();
AnabaticEngine* engine = AnabaticEngine::get( cell );
if (not engine) {
engine = AnabaticEngine::create( cell );
} else
cerr << Warning( "%s already has a Anabatic engine.", getString(cell).c_str() ) << endl;
return engine;
}
AnabaticEngine* GraphicAnabaticEngine::getForFramework ( unsigned int flags )
{
// Currently, only one framework is avalaible: Alliance.
AnabaticEngine* engine = AnabaticEngine::get( getCell() );
if (engine) return engine;
if (flags & CreateEngine) {
engine = createEngine();
if (not engine)
throw Error( "Failed to create Anabatic engine on %s.", getString(getCell()).c_str() );
} else {
throw Error( "AnabaticEngine not created yet, run the global router first." );
}
return engine;
}
void GraphicAnabaticEngine::_runTest ()
{
if (_viewer) _viewer->emitCellAboutToChange();
AnabaticEngine* engine = getForFramework( CreateEngine );
engine->getSouthWestGCell()->doGrid();
// GCell* row0 = getSouthWestGCell();
// DbU::Unit xcorner = getCell()->getAbutmentBox().getXMin();
// DbU::Unit ycorner = getCell()->getAbutmentBox().getYMin();
// cdebug.log(119,1) << "row0: " << row0 << endl;
// GCell* row1 = row0->hcut( ycorner+DbU::fromLambda(50.0) );
// cdebug.tabw(119,-1);
// cdebug.log(119,1) << "row1: " << row1 << endl;
// GCell* row2 = row1->hcut( ycorner+DbU::fromLambda(2*50.0) );
// cdebug.tabw(119,-1);
// cdebug.log(119,1) << "row2: " << row2 << endl;
// row0 = row0->vcut( xcorner+DbU::fromLambda(50.0) );
// cdebug.tabw(119,-1);
// cdebug.log(119,1) << "row0+1: " << row0 << endl;
// row0 = row0->vcut( xcorner+DbU::fromLambda(3*50.0) );
// cdebug.tabw(119,-1);
// cdebug.log(119,1) << "row0+2: " << row0 << endl;
// row0 = row0->vcut( xcorner+DbU::fromLambda(5*50.0) );
// cdebug.tabw(119,-1);
// cdebug.log(119,1) << "row0+3: " << row0 << endl;
// row1 = row1->vcut( xcorner+DbU::fromLambda(2*50.0) );
// cdebug.tabw(119,-1);
// cdebug.log(119,1) << "row1+1: " << row1 << endl;
// cdebug.tabw(119,-1);
// gcell = gcell->hcut( ycut+DbU::fromLambda(50.0) );
// cerr << "New GCell: " << gcell << endl;
// DbU::Unit ycut = getCell()->getAbutmentBox().getYMin() + DbU::fromLambda(50.0);
// for ( ; ycut < getCell()->getAbutmentBox().getYMax() ; ycut += DbU::fromLambda(50.0) ) {
// cdebug.log(119,2) << "H cut line (y coordinate): " << DbU::getValueString(ycut) << endl;
// gcell = gcell->hcut( ycut );
// cerr << gcell << endl;
// cdebug.tabw(119,-2);
// }
// if (_viewer) _viewer->emitCellChanged();
}
void GraphicAnabaticEngine::addToMenu ( CellViewer* viewer )
{
assert( _viewer == NULL );
_viewer = viewer;
if (_viewer->hasMenuAction("placeAndRoute.anabatic")) {
cerr << Warning( "GraphicAnabaticEngine::addToMenu() - Anabatic engine already hooked in." ) << endl;
return;
}
_viewer->addToMenu( "placeAndRoute.anabatic"
, "Anabatic - &Test Run"
, "Perform a test run of Anabatic on the design"
, std::bind(&GraphicAnabaticEngine::_runTest,this)
);
}
const Name& GraphicAnabaticEngine::getName () const
{ return AnabaticEngine::staticGetName(); }
Cell* GraphicAnabaticEngine::getCell ()
{
if (_viewer == NULL) {
throw Error( "<b>Anabatic:</b> GraphicAnabaticEngine not bound to any Viewer." );
return NULL;
}
if (_viewer->getCell() == NULL) {
throw Error( "<b>Anabatic:</b> No Cell is loaded into the Viewer." );
return NULL;
}
return _viewer->getCell();
}
GraphicAnabaticEngine* GraphicAnabaticEngine::grab ()
{
if (not _references)
_singleton = new GraphicAnabaticEngine ();
_references++;
return _singleton;
}
size_t GraphicAnabaticEngine::release ()
{
--_references;
if (not _references) {
delete _singleton;
_singleton = NULL;
}
return _references;
}
GraphicAnabaticEngine::GraphicAnabaticEngine ()
: GraphicTool()
, _viewer (NULL)
{
addDrawGo( "Anabatic::GCell", initGCell, drawGCell );
addDrawGo( "Anabatic::Edge" , initEdge , drawEdge );
}
GraphicAnabaticEngine::~GraphicAnabaticEngine ()
{ }
} // Anabatic namespace.

127
anabatic/src/Matrix.cpp Normal file
View File

@ -0,0 +1,127 @@
// -*- mode: C++; explicit-buffer-name: "Matrix.cpp<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Matrix.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include <iostream>
#include "hurricane/Cell.h"
#include "anabatic/Matrix.h"
#include "anabatic/GCell.h"
namespace Anabatic {
using std::cout;
using std::cerr;
using std::endl;
using std::ostringstream;
using Hurricane::Error;
Matrix::Matrix ()
: _area ()
, _side (1)
, _gcells()
, _imax (0)
, _jmax (0)
{ }
Matrix::Matrix ( Box area, DbU::Unit side )
: _area (area)
, _side (side)
, _gcells()
, _imax (0)
, _jmax (0)
{
_imax = _area.getWidth () / side;
_jmax = _area.getHeight() / side;
_gcells.resize( _imax*_jmax );
}
Matrix::~Matrix ()
{ }
void Matrix::setCell ( Cell* cell, DbU::Unit side )
{
_area = cell->getAbutmentBox();
_side = side;
_imax = _area.getWidth () / side;
_jmax = _area.getHeight() / side;
_gcells.resize( _imax*_jmax );
}
void Matrix::updateLookup ( GCell* gcell )
{
cdebug.log(110,1) << "Matrix::updateLookup(): " << gcell << endl;
Box gcellBb = gcell->getBoundingBox();
Box updateArea = _area.getIntersection( gcellBb );
if (updateArea.isEmpty()) {
cerr << Error( "Matrix::updateLookup(): %s is not under area of %s."
, getString(gcell).c_str()
, getString(this).c_str()
) << endl;
}
Index indexMin = Index( this, updateArea.getXMin() , updateArea.getYMin() );
Index indexMax = Index( this, updateArea.getXMax()-1, updateArea.getYMax()-1 );
int xspan = indexMax.i() - indexMin.i();
cdebug.log(110) << "indexMin:" << indexMin << endl;
cdebug.log(110) << "indexMax:" << indexMax << endl;
int index = indexMin.index();
while ( index <= indexMax.index() ) {
_gcells[index] = gcell;
if (index <= indexMax.j()) ++index;
else index += _imax - xspan;
}
cdebug.tabw(110,-1);
}
string Matrix::_getTypeName () const
{ return "Matrix"; }
string Matrix::_getString () const
{
ostringstream os;
os << "<" << _getTypeName() << " " << _imax << "x" << _jmax
<< " " << _area << "/" << DbU::getValueString(_side) << ">";
return os.str();
}
Record* Matrix::_getRecord () const
{
Record* record = new Record( _getString() );
record->add( getSlot ("_area" , _area ) );
record->add( DbU::getValueSlot("_side" , &_side ) );
record->add( getSlot ("_imax" , _imax ) );
record->add( getSlot ("_jmax" , _jmax ) );
record->add( getSlot ("_gcells", &_gcells) );
return record;
}
} // Anabatic namespace;

View File

@ -0,0 +1,94 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyAnabatic.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/isobar/PyCell.h"
#include "anabatic/PyAnabaticEngine.h"
#include "anabatic/PyGraphicAnabaticEngine.h"
namespace Anabatic {
using std::cerr;
using std::endl;
using Hurricane::tab;
using Isobar::__cs;
using CRL::PyTypeToolEngine;
using CRL::PyTypeGraphicTool;
#if !defined(__PYTHON_MODULE__)
// +=================================================================+
// | "PyAnabatic" Shared Library Code Part |
// +=================================================================+
# else // End of PyHurricane Shared Library Code Part.
// +=================================================================+
// | "PyAnabatic" Python Module Code Part |
// +=================================================================+
extern "C" {
// +-------------------------------------------------------------+
// | "PyAnabatic" Module Methods |
// +-------------------------------------------------------------+
static PyMethodDef PyAnabatic_Methods[] =
{ {NULL, NULL, 0, NULL} /* sentinel */
};
// ---------------------------------------------------------------
// Module Initialization : "initAnabatic ()"
DL_EXPORT(void) initAnabatic () {
cdebug.log(32) << "initAnabatic()" << endl;
PyAnabaticEngine_LinkPyType();
PyGraphicAnabaticEngine_LinkPyType();
PYTYPE_READY_SUB( AnabaticEngine , ToolEngine );
PYTYPE_READY_SUB( GraphicAnabaticEngine, GraphicTool );
PyObject* module = Py_InitModule( "Anabatic", PyAnabatic_Methods );
if (module == NULL) {
cerr << "[ERROR]\n"
<< " Failed to initialize Anabatic module." << endl;
return;
}
Py_INCREF( &PyTypeAnabaticEngine );
PyModule_AddObject( module, "AnabaticEngine", (PyObject*)&PyTypeAnabaticEngine );
Py_INCREF( &PyTypeGraphicAnabaticEngine );
PyModule_AddObject( module, "GraphicAnabaticEngine", (PyObject*)&PyTypeGraphicAnabaticEngine );
}
} // End of extern "C".
#endif // End of Python Module Code Part.
} // End of Anabatic namespace.

View File

@ -0,0 +1,217 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyAnabaticEngine.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyCell.h"
#include "hurricane/viewer/PyCellViewer.h"
#include "hurricane/viewer/ExceptionWidget.h"
#include "hurricane/Cell.h"
#include "anabatic/PyAnabaticEngine.h"
#include <functional>
# undef ACCESS_OBJECT
# undef ACCESS_CLASS
# define ACCESS_OBJECT _baseObject._object
# define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject)
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(AnabaticEngine,engine,function)
namespace Anabatic {
using std::cerr;
using std::endl;
using std::hex;
using std::ostringstream;
using Hurricane::tab;
using Hurricane::Exception;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::ExceptionWidget;
using Isobar::ProxyProperty;
using Isobar::ProxyError;
using Isobar::ConstructorError;
using Isobar::HurricaneError;
using Isobar::HurricaneWarning;
using Isobar::ParseOneArg;
using Isobar::ParseTwoArg;
using Isobar::PyCell;
using Isobar::PyCell_Link;
using Isobar::PyCellViewer;
using Isobar::PyTypeCellViewer;
using CRL::PyToolEngine;
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()) { \
if (ExceptionWidget::catchAllWrapper( std::bind(&AnabaticEngine::FUNC_NAME,SELF_OBJECT) )) { \
PyErr_SetString( HurricaneError, #FUNC_NAME "() has thrown an exception (C++)." ); \
return NULL; \
} \
} else { \
SELF_OBJECT->FUNC_NAME(); \
} \
HCATCH \
Py_RETURN_NONE; \
}
// +=================================================================+
// | "PyAnabaticEngine" Python Module Code Part |
// +=================================================================+
static PyObject* PyAnabaticEngine_get ( PyObject*, PyObject* args )
{
cdebug.log(32) << "PyAnabaticEngine_get()" << endl;
AnabaticEngine* engine = NULL;
HTRY
PyObject* arg0;
if (not ParseOneArg("Anabatic.get", args, CELL_ARG, &arg0)) return NULL;
engine = AnabaticEngine::get(PYCELL_O(arg0));
HCATCH
return PyAnabaticEngine_Link(engine);
}
static PyObject* PyAnabaticEngine_create ( PyObject*, PyObject* args )
{
cdebug.log(32) << "PyAnabaticEngine_create()" << endl;
AnabaticEngine* engine = NULL;
HTRY
PyObject* arg0;
if (not ParseOneArg("Anabatic.get", args, CELL_ARG, &arg0)) return NULL;
Cell* cell = PYCELL_O(arg0);
engine = AnabaticEngine::get(cell);
if (engine == NULL) {
engine = AnabaticEngine::create(cell);
} else
cerr << Warning("%s already has a Anabatic engine.",getString(cell).c_str()) << endl;
HCATCH
return PyAnabaticEngine_Link(engine);
}
static PyObject* PyAnabaticEngine_setViewer ( PyAnabaticEngine* self, PyObject* args )
{
cdebug.log(32) << "PyAnabaticEngine_setViewer ()" << endl;
HTRY
METHOD_HEAD( "AnabaticEngine.setViewer()" )
PyObject* pyViewer = NULL;
if (not PyArg_ParseTuple(args,"O:EtesianEngine.setViewer()",&pyViewer)) {
PyErr_SetString( ConstructorError, "Bad parameters given to EtesianEngine.setViewer()." );
return NULL;
}
if (IsPyCellViewer(pyViewer)) {
engine->setViewer( PYCELLVIEWER_O(pyViewer) );
}
HCATCH
Py_RETURN_NONE;
}
PyObject* PyAnabaticEngine_runTest ( PyAnabaticEngine* self, PyObject* args )
{
cdebug.log(32) << "PyAnabaticEngine_runTest()" << endl;
HTRY
METHOD_HEAD("AnabaticEngine.runTest()")
unsigned int flags = 0;
if (PyArg_ParseTuple(args,"I:AnabaticEngine.runTest", &flags)) {
if (engine->getViewer()) {
if (ExceptionWidget::catchAllWrapper( std::bind(&AnabaticEngine::_runTest,engine) )) {
PyErr_SetString( HurricaneError, "AnabaticEngine::runTest() has thrown an exception (C++)." );
return NULL;
}
} else {
engine->_runTest();
}
} else {
PyErr_SetString(ConstructorError, "AnabaticEngine.runGlobalRouter(): Invalid number/bad type of parameter.");
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
// Standart Accessors (Attributes).
// Standart Destroy (Attribute).
DBoDestroyAttribute(PyAnabaticEngine_destroy,PyAnabaticEngine)
PyMethodDef PyAnabaticEngine_Methods[] =
{ { "get" , (PyCFunction)PyAnabaticEngine_get , METH_VARARGS|METH_STATIC
, "Returns the Anabatic engine attached to the Cell, None if there isnt't." }
, { "create" , (PyCFunction)PyAnabaticEngine_create , METH_VARARGS|METH_STATIC
, "Create a Anabatic engine on this cell." }
, { "setViewer" , (PyCFunction)PyAnabaticEngine_setViewer , METH_VARARGS
, "Associate a Viewer to this AnabaticEngine." }
, { "runTest" , (PyCFunction)PyAnabaticEngine_runTest , METH_VARARGS
, "Run the test procedure." }
, { "destroy" , (PyCFunction)PyAnabaticEngine_destroy , METH_NOARGS
, "Destroy the associated hurricane object. The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
DBoDeleteMethod(AnabaticEngine)
PyTypeObjectLinkPyType(AnabaticEngine)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyAnabaticEngine" Shared Library Code Part |
// +=================================================================+
// Link/Creation Method.
PyTypeInheritedObjectDefinitions(AnabaticEngine,PyToolEngine)
DBoLinkCreateMethod(AnabaticEngine)
#endif // Shared Library Code Part.
} // extern "C".
} // Anabatic namespace.

View File

@ -0,0 +1,122 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyGraphicAnabaticEngine.cpp" |
// +-----------------------------------------------------------------+
#include "anabatic/PyGraphicAnabaticEngine.h"
#include "hurricane/isobar/PyCell.h"
#include "hurricane/Cell.h"
#undef ACCESS_OBJECT
#undef ACCESS_CLASS
#define ACCESS_OBJECT _baseObject._object
#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject)
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(GraphicAnabaticEngine,gengine,function)
namespace Anabatic {
using namespace Hurricane;
using namespace Isobar;
extern "C" {
// +=================================================================+
// | "PyGraphicAnabaticEngine" Python Module Code Part |
// +=================================================================+
#if defined(__PYTHON_MODULE__)
// +-------------------------------------------------------------+
// | "PyGraphicAnabaticEngine" Attribute Methods |
// +-------------------------------------------------------------+
static PyObject* PyGraphicAnabaticEngine_grab ( PyObject* )
{
cdebug.log(32) << "PyGraphicAnabaticEngine_grab()" << endl;
PyGraphicAnabaticEngine* pyGraphicAnabaticEngine = NULL;
HTRY
pyGraphicAnabaticEngine = PyObject_NEW ( PyGraphicAnabaticEngine, &PyTypeGraphicAnabaticEngine );
if ( pyGraphicAnabaticEngine == NULL ) return NULL;
pyGraphicAnabaticEngine->ACCESS_OBJECT = GraphicAnabaticEngine::grab();
HCATCH
return (PyObject*)pyGraphicAnabaticEngine;
}
static PyObject* PyGraphicAnabaticEngine_getCell ( PyGraphicAnabaticEngine* self )
{
cdebug.log(32) << "PyGraphicAnabaticEngine_getCell ()" << endl;
Cell* cell = NULL;
HTRY
METHOD_HEAD("GraphicAnabaticEngine.getCell()")
cell = gengine->getCell ();
HCATCH
if (cell == NULL) Py_RETURN_NONE;
return PyCell_Link(cell);
}
GetNameMethod(GraphicAnabaticEngine, gengine)
// Standart destroy (Attribute).
PyMethodDef PyGraphicAnabaticEngine_Methods[] =
{ { "grab" , (PyCFunction)PyGraphicAnabaticEngine_grab , METH_NOARGS|METH_STATIC
, "Returns the GraphicAnabaticEngine singleton." }
, { "getName" , (PyCFunction)PyGraphicAnabaticEngine_getName , METH_NOARGS
, "Returns the name of the GraphicAnabaticEngine (class attribute)." }
, { "getCell" , (PyCFunction)PyGraphicAnabaticEngine_getCell , METH_NOARGS
, "Returns the Cell on which this GraphicAnabaticEngine is attached." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
// ---------------------------------------------------------------
// PyGraphicAnabaticEngine Type Methods.
PythonOnlyDeleteMethod(GraphicAnabaticEngine)
PyTypeObjectLinkPyType(GraphicAnabaticEngine)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyGraphicAnabaticEngine" Shared Library Code Part |
// +=================================================================+
// Link/Creation Method.
LinkCreateMethod(GraphicAnabaticEngine)
PyTypeInheritedObjectDefinitions(GraphicAnabaticEngine,GraphicTool)
#endif // End of Shared Library Code Part.
} // extern "C".
} // CRL namespace.

View File

@ -0,0 +1,92 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/AnabaticEngine.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_ANABATIC_ENGINE_H
#define ANABATIC_ANABATIC_ENGINE_H
#include <string>
namespace Hurricane {
class Name;
class Cell;
class Instance;
class CellViewer;
}
#include "crlcore/ToolEngine.h"
#include "anabatic/Configuration.h"
#include "anabatic/Matrix.h"
namespace Anabatic {
using std::string;
using Hurricane::Name;
using Hurricane::Record;
using Hurricane::Cell;
using Hurricane::CellViewer;
using CRL::ToolEngine;
class GCell;
class AnabaticEngine : public ToolEngine {
public:
typedef ToolEngine Super;
public:
static AnabaticEngine* create ( Cell* );
static AnabaticEngine* get ( const Cell* );
static const Name& staticGetName ();
virtual const Name& getName () const;
virtual Configuration* getConfiguration ();
inline CellViewer* getViewer () const;
inline void setViewer ( CellViewer* );
inline GCell* getSouthWestGCell () const;
inline void _updateLookup ( GCell* );
void _runTest ();
// Inspector support.
virtual Record* _getRecord () const;
virtual string _getString () const;
virtual string _getTypeName () const;
protected:
AnabaticEngine ( Cell* );
virtual ~AnabaticEngine ();
virtual void _postCreate ();
virtual void _preDestroy ();
private:
AnabaticEngine ( const AnabaticEngine& );
AnabaticEngine& operator= ( const AnabaticEngine& );
private:
static Name _toolName;
Configuration* _configuration;
Matrix _matrix;
GCell* _southWestGCell;
CellViewer* _viewer;
};
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _southWestGCell; }
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::AnabaticEngine);
#endif // ANABATIC_ANABATIC_ENGINE_H

View File

@ -0,0 +1,159 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.h<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/Configuration.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_CONFIGURATION_H
#define ANABATIC_CONFIGURATION_H
#include <string>
#include <vector>
#include "hurricane/DbU.h"
namespace Hurricane {
class Layer;
class Cell;
}
namespace CRL {
class CellGauge;
class RoutingGauge;
class RoutingLayerGauge;
}
#include "anabatic/Constants.h"
namespace Anabatic {
using std::string;
using Hurricane::Record;
using Hurricane::Name;
using Hurricane::Layer;
using Hurricane::DbU;
using Hurricane::Cell;
using CRL::CellGauge;
using CRL::RoutingGauge;
using CRL::RoutingLayerGauge;
// -------------------------------------------------------------------
// Class : "Anabatic::Configuration" (decorator).
class Configuration {
public:
// Constructor & Destructor.
virtual ~Configuration ();
virtual Configuration* clone () const = 0;
// Methods.
virtual bool isGMetal ( const Layer* ) const = 0;
virtual bool isGContact ( const Layer* ) const = 0;
virtual size_t getDepth () const = 0;
virtual size_t getAllowedDepth () const = 0;
virtual size_t getLayerDepth ( const Layer* ) const = 0;
virtual CellGauge* getCellGauge () const = 0;
virtual RoutingGauge* getRoutingGauge () const = 0;
virtual RoutingLayerGauge* getLayerGauge ( size_t depth ) const = 0;
virtual const Layer* getRoutingLayer ( size_t depth ) const = 0;
virtual Layer* getContactLayer ( size_t depth ) const = 0;
virtual DbU::Unit getSliceHeight () const = 0;
virtual DbU::Unit getSliceStep () const = 0;
virtual DbU::Unit getPitch ( size_t depth, Flags flags ) const = 0;
virtual DbU::Unit getOffset ( size_t depth ) const = 0;
virtual DbU::Unit getWireWidth ( size_t depth ) const = 0;
virtual DbU::Unit getExtensionCap ( size_t depth ) const = 0;
virtual Flags getDirection ( size_t depth ) const = 0;
virtual DbU::Unit getPitch ( const Layer*, Flags flags ) const = 0;
virtual DbU::Unit getOffset ( const Layer* ) const = 0;
virtual DbU::Unit getWireWidth ( const Layer* ) const = 0;
virtual DbU::Unit getExtensionCap ( const Layer* ) const = 0;
virtual Flags getDirection ( const Layer* ) const = 0;
virtual void setAllowedDepth ( size_t ) = 0;
virtual void print ( Cell* ) const = 0;
virtual Record* _getRecord () const = 0;
virtual string _getString () const = 0;
virtual string _getTypeName () const = 0;
protected:
Configuration ();
private:
Configuration ( const Configuration& );
Configuration& operator= ( const Configuration& );
private:
static Configuration* _default;
};
// -------------------------------------------------------------------
// Class : "Anabatic::ConfigurationConcrete".
class ConfigurationConcrete : public Configuration {
friend class Configuration;
public:
// Constructor & Destructor.
ConfigurationConcrete ( const CellGauge* cg=NULL, const RoutingGauge* rg=NULL );
virtual ~ConfigurationConcrete ();
virtual ConfigurationConcrete* clone () const;
// Methods.
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 CellGauge* getCellGauge () 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 getSliceHeight () const;
virtual DbU::Unit getSliceStep () const;
virtual DbU::Unit getPitch ( size_t depth, Flags flags ) const;
virtual DbU::Unit getOffset ( size_t depth ) const;
virtual DbU::Unit getWireWidth ( size_t depth ) const;
virtual DbU::Unit getExtensionCap ( size_t depth ) const;
virtual Flags getDirection ( size_t depth ) const;
virtual DbU::Unit getPitch ( const Layer*, Flags flags ) const;
virtual DbU::Unit getOffset ( const Layer* ) const;
virtual DbU::Unit getWireWidth ( const Layer* ) const;
virtual DbU::Unit getExtensionCap ( const Layer* ) const;
virtual Flags getDirection ( const Layer* ) const;
virtual void setAllowedDepth ( size_t );
virtual void print ( Cell* ) const;
virtual Record* _getRecord () const;
virtual string _getString () const;
virtual string _getTypeName () const;
protected:
// Attributes.
const Layer* _gmetalh;
const Layer* _gmetalv;
const Layer* _gcontact;
CellGauge* _cg;
RoutingGauge* _rg;
std::vector<DbU::Unit> _extensionCaps;
size_t _allowedDepth;
private:
ConfigurationConcrete ( const ConfigurationConcrete& );
ConfigurationConcrete& operator= ( const ConfigurationConcrete& );
void _setTopRoutingLayer ( Name name );
};
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::Configuration);
INSPECTOR_P_SUPPORT(Anabatic::ConfigurationConcrete);
#endif // ANABATIC_CONFIGURATION_H

View File

@ -0,0 +1,60 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/Constants.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_CONSTANTS_H
#define ANABATIC_CONSTANTS_H
#include "hurricane/Flags.h"
namespace Anabatic {
class Flags : public Hurricane::BaseFlags {
public:
enum Flag { NoFlags = 0
, Horizontal = (1<<0)
, Vertical = (1<<1)
, SourceGCell = (1<<2)
, TargetGCell = (1<<3)
, MoveSide = (1<<4)
, Invalidated = (1<<5)
, WestSide = Horizontal|TargetGCell
, EastSide = Horizontal|SourceGCell
, SouthSide = Vertical |TargetGCell
, NorthSide = Vertical |SourceGCell
, AllSides = WestSide|EastSide|SouthSide|NorthSide
, PitchAbove = (1<<6)
, PitchBelow = (1<<7)
};
public:
inline Flags ( unsigned int flags = NoFlags );
inline Flags ( BaseFlags );
virtual ~Flags ();
virtual std::string _getTypeName () const;
virtual std::string _getString () const;
};
Flags::Flags ( unsigned int flags ) : BaseFlags(flags) { }
Flags::Flags ( BaseFlags base ) : BaseFlags(base) { }
} // Anabatic namespace.
INSPECTOR_PV_SUPPORT(Anabatic::Flags)
#endif // ANABATIC_CONSTANTS_H

View File

@ -0,0 +1,115 @@
// -*- mode: C++; explicit-buffer-name: "Edge.h<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/Edge.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_EDGE_H
#define ANABATIC_EDGE_H
#include <string>
#include "hurricane/Name.h"
#include "hurricane/Interval.h"
#include "hurricane/Box.h"
#include "hurricane/ExtensionGo.h"
#include "anabatic/Constants.h"
namespace Anabatic {
using std::string;
using Hurricane::Name;
using Hurricane::Record;
using Hurricane::DbU;
using Hurricane::Interval;
using Hurricane::Box;
using Hurricane::Cell;
using Hurricane::ExtensionGo;
class GCell;
class Edge : public ExtensionGo {
public:
typedef ExtensionGo Super;
public:
static Edge* create ( GCell* source, GCell* target, Flags flags=Flags::NoFlags );
virtual void destroy ();
public:
inline unsigned int getCapacity () const;
inline unsigned int getRealOccupancy () const;
inline unsigned int getEstimateOccupancy () const;
inline GCell* getSource () const;
inline GCell* getTarget () const;
GCell* getOpposite ( const GCell* ) const;
inline DbU::Unit getAxis () const;
DbU::Unit getAxisMin () const;
Interval getSide () const;
inline const Flags& flags () const;
inline Flags& flags ();
inline void invalidate ();
inline void revalidate () const;
void _setSource ( GCell* );
void _setTarget ( GCell* );
private:
void _revalidate ();
public:
// ExtensionGo support.
inline const Name& staticGetName ();
virtual const Name& getName () const;
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual Box getBoundingBox () const;
public:
// Inspector support.
virtual string _getTypeName () const;
virtual string _getString () const;
virtual Record* _getRecord () const;
protected:
Edge ( GCell* source, GCell* target, Flags flags );
virtual ~Edge ();
virtual void _postCreate ();
virtual void _preDestroy ();
private:
Edge ( const Edge& );
Edge& operator= ( const Edge& );
private:
static Name _extensionName;
Flags _flags;
unsigned int _capacity;
unsigned int _realOccupancy;
float _estimateOccupancy;
GCell* _source;
GCell* _target;
DbU::Unit _axis;
};
inline const Name& Edge::staticGetName () { return _extensionName; }
inline unsigned int Edge::getCapacity () const { return _capacity; }
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
inline GCell* Edge::getSource () const { return _source; }
inline GCell* Edge::getTarget () const { return _target; }
inline DbU::Unit Edge::getAxis () const { return _axis; }
inline const Flags& Edge::flags () const { return _flags; }
inline Flags& Edge::flags () { return _flags; }
inline void Edge::invalidate () { _flags |= Flags::Invalidated; }
inline void Edge::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast<Edge*>(this)->_revalidate(); }
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::Edge);
#endif // ANABATIC_EDGE_H

View File

@ -0,0 +1,132 @@
// -*- mode: C++; explicit-buffer-name: "GCell.h<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/GCell.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_GCELL_H
#define ANABATIC_GCELL_H
#include <vector>
#include <string>
#include "hurricane/Name.h"
#include "hurricane/Box.h"
#include "hurricane/Cell.h"
#include "hurricane/ExtensionGo.h"
#include "anabatic/Edge.h"
namespace Anabatic {
using std::string;
using std::vector;
using Hurricane::Name;
using Hurricane::Record;
using Hurricane::DbU;
using Hurricane::Point;
using Hurricane::Interval;
using Hurricane::Box;
using Hurricane::Cell;
class AnabaticEngine;
class GCell : public ExtensionGo {
public:
typedef ExtensionGo Super;
public:
static Box getBorder ( const GCell*, const GCell* );
public:
static GCell* create ( AnabaticEngine* );
virtual void destroy ();
public:
inline AnabaticEngine* getAnabatic () const;
inline DbU::Unit getXMin () const;
inline DbU::Unit getYMin () const;
inline DbU::Unit getXMax () const;
inline DbU::Unit getYMax () const;
inline Interval getSide ( Flags direction ) const;
inline Point getCenter () const;
GCell* hcut ( DbU::Unit y );
GCell* vcut ( DbU::Unit x );
bool doGrid ();
inline const Flags& flags () const;
inline Flags& flags ();
void _add ( Edge* edge, Flags side );
void _remove ( Edge* edge, Flags side=Flags::AllSides );
private:
void _revalidate ();
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
public:
// ExtensionGo support.
inline const Name& staticGetName ();
virtual const Name& getName () const;
virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual Box getBoundingBox () const;
public:
// Inspector support.
virtual string _getTypeName () const;
virtual string _getString () const;
virtual Record* _getRecord () const;
protected:
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
virtual ~GCell ();
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
virtual void _postCreate ();
virtual void _preDestroy ();
private:
GCell ( const GCell& );
GCell& operator= ( const GCell& );
private:
static Name _extensionName;
AnabaticEngine* _anabatic;
Flags _flags;
vector<Edge*> _westEdges;
vector<Edge*> _eastEdges;
vector<Edge*> _southEdges;
vector<Edge*> _northEdges;
DbU::Unit _xmin;
DbU::Unit _ymin;
};
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
inline DbU::Unit GCell::getXMin () const { return _xmin; }
inline DbU::Unit GCell::getYMin () const { return _ymin; }
inline const Flags& GCell::flags () const { return _flags; }
inline Flags& GCell::flags () { return _flags; }
inline DbU::Unit GCell::getXMax () const
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax()
: _eastEdges[0]->getOpposite(this)->getXMin(); }
inline DbU::Unit GCell::getYMax () const
{ return _northEdges.empty() ? getCell()->getAbutmentBox().getYMax()
: _northEdges[0]->getOpposite(this)->getYMin(); }
inline Point GCell::getCenter () const
{ return Point( (getXMin()+getXMax())/2, (getYMin()+getYMax())/2); }
inline Interval GCell::getSide ( Flags direction ) const
{
if (direction.isset(Flags::Vertical)) return Interval( getYMin(), getYMax() );
return Interval( getXMin(), getXMax() );
}
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::GCell);
#endif // ANABATIC_GCELL_H

View File

@ -0,0 +1,90 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/GraphicAnabaticEngine.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_GRAPHIC_ANABATIC_ENGINE_H
#define ANABATIC_GRAPHIC_ANABATIC_ENGINE_H
#include <functional>
#include <QObject>
namespace Hurricane {
class Go;
class BasicLayer;
class Transformation;
class CellWidget;
class CellViewer;
}
#include "crlcore/GraphicToolEngine.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using Hurricane::Go;
using Hurricane::Box;
using Hurricane::BasicLayer;
using Hurricane::Transformation;
using Hurricane::CellWidget;
using Hurricane::CellViewer;
using CRL::GraphicTool;
// -------------------------------------------------------------------
// Class : "Anabatic::GraphicAnabaticEngine".
class GraphicAnabaticEngine : public GraphicTool {
Q_OBJECT;
public:
enum Flags { NoFlags=0x0000, CreateEngine=0x0001 };
public:
AnabaticEngine* createEngine ();
AnabaticEngine* getForFramework ( unsigned int flags );
static void initGCell ( CellWidget* );
static void drawGCell ( CellWidget*
, const Go*
, const BasicLayer*
, const Box&
, const Transformation&
);
static void initEdge ( CellWidget* );
static void drawEdge ( CellWidget*
, const Go*
, const BasicLayer*
, const Box&
, const Transformation&
);
static GraphicAnabaticEngine* grab ();
virtual const Name& getName () const;
Cell* getCell ();
virtual size_t release ();
virtual void addToMenu ( CellViewer* );
protected:
static size_t _references;
static GraphicAnabaticEngine* _singleton;
CellViewer* _viewer;
protected:
GraphicAnabaticEngine ();
virtual ~GraphicAnabaticEngine ();
void _runTest ();
};
} // Anabatic namespace.
#endif // ANABATIC_GRAPHIC_ANABATIC_ENGINE_H

View File

@ -0,0 +1,210 @@
// -*- mode: C++; explicit-buffer-name: "Matrix.h<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/Matrix.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_MATRIX_H
#define ANABATIC_MATRIX_H
#include <string>
#include <vector>
#include <iostream>
#include "hurricane/Box.h"
namespace Hurricane {
class Cell;
}
namespace Anabatic {
using std::string;
using std::vector;
using std::ostream;
using Hurricane::Record;
using Hurricane::DbU;
using Hurricane::Point;
using Hurricane::Box;
using Hurricane::Cell;
class GCell;
class Matrix {
public:
class Index {
public:
inline Index ( Matrix*, int index );
inline Index ( Matrix*, int i, int j );
inline Index ( Matrix*, DbU::Unit x, DbU::Unit y );
inline Index ( Matrix*, Point position );
inline Matrix* matrix () const;
inline const int& index () const;
inline int& index ();
inline bool valid () const;
inline int i () const;
inline int j () const;
inline Index& west ();
inline Index& east ();
inline Index& south ();
inline Index& north ();
private:
Matrix* _matrix;
int _index;
};
public:
Matrix ();
Matrix ( Box area, DbU::Unit side );
~Matrix ();
inline Box getArea () const;
inline DbU::Unit getSide () const;
inline int getIMax () const;
inline int getJMax () const;
inline int index2i ( int ) const;
inline int index2j ( int ) const;
inline int index2i ( const Index& ) const;
inline int index2j ( const Index& ) const;
inline int ij2index ( int i, int j ) const;
inline int xy2index ( DbU::Unit x, DbU::Unit y ) const;
inline int xy2index ( Point ) const;
inline Index& west ( Index& ) const;
inline Index& east ( Index& ) const;
inline Index& south ( Index& ) const;
inline Index& north ( Index& ) const;
inline GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const;
inline GCell* getUnder ( Point ) const;
void setCell ( Cell*, DbU::Unit side );
void updateLookup ( GCell* );
// Inspector support.
virtual Record* _getRecord () const;
virtual string _getString () const;
virtual string _getTypeName () const;
private:
Matrix ( const Matrix& );
Matrix& operator= ( const Matrix& );
private:
Box _area;
DbU::Unit _side;
vector<GCell*> _gcells;
int _imax;
int _jmax;
};
// Matrix inline functions.
inline Box Matrix::getArea () const { return _area; }
inline DbU::Unit Matrix::getSide () const { return _side; }
inline int Matrix::getIMax () const { return _imax; }
inline int Matrix::getJMax () const { return _jmax; }
inline int Matrix::index2i ( int index ) const
{ return ((index >= 0) and (index < _imax*_jmax+1)) ? index % _imax : -1; }
inline int Matrix::index2i ( const Index& index ) const
{ return (index.valid()) ? index.index() % _imax : -1; }
inline int Matrix::index2j ( int index ) const
{ return ((index >= 0) and (index < _imax*_jmax+1)) ? index / _imax : -1; }
inline int Matrix::index2j ( const Index& index ) const
{ return (index.valid()) ? index.index() / _imax : -1; }
inline int Matrix::ij2index ( int i, int j ) const
{
if ((i < 0) or (i >= _imax)) return -1;
if ((j < 0) or (j >= _jmax)) return -1;
return j*_jmax + i;
}
inline int Matrix::xy2index ( DbU::Unit x, DbU::Unit y ) const
{ return ij2index( (x - _area.getXMin()) / _side, (y - _area.getYMin()) / _side ); }
inline int Matrix::xy2index ( Point p ) const
{ return xy2index( p.getX(), p.getY() ); }
inline Matrix::Index& Matrix::west ( Matrix::Index& index ) const
{
if (index.valid()) {
if (index.index() % _imax) index.index() -= 1;
else index.index() = -1;
}
return index;
}
inline Matrix::Index& Matrix::east ( Matrix::Index& index ) const
{
if (index.valid()) {
if ((index.index() % _imax) < _imax-1) index.index() += 1;
else index.index() = -1;
}
return index;
}
inline Matrix::Index& Matrix::south ( Matrix::Index& index ) const
{
if (index.valid()) {
if (index.index() >= _imax) index.index() -= _imax;
else index.index() = -1;
}
return index;
}
inline Matrix::Index& Matrix::north ( Matrix::Index& index ) const
{
if (index.valid()) {
if (index.index() >= _imax*(_jmax-1)) index.index() += _imax;
else index.index() = -1;
}
return index;
}
inline GCell* Matrix::getUnder ( DbU::Unit x, DbU::Unit y ) const
{ int index = xy2index(x,y); return (index < 0) ? NULL : _gcells[index]; }
inline GCell* Matrix::getUnder ( Point p ) const
{ return getUnder( p.getX(), p.getY() ); }
// Matrix::Index inline functions.
inline Matrix::Index::Index ( Matrix* m, int index ) : _matrix(m), _index(index) { }
inline Matrix::Index::Index ( Matrix* m, int i, int j ) : _matrix(m), _index(m->ij2index(i,j)) { }
inline Matrix::Index::Index ( Matrix* m, DbU::Unit x, DbU::Unit y ) : _matrix(m), _index(m->xy2index(x,y)) { }
inline Matrix::Index::Index ( Matrix* m, Point position ) : _matrix(m), _index(m->xy2index(position)) { }
inline Matrix* Matrix::Index::matrix () const { return _matrix; }
inline const int& Matrix::Index::index () const { return _index; }
inline int& Matrix::Index::index () { return _index; }
inline bool Matrix::Index::valid () const { return _index >= 0; }
inline int Matrix::Index::i () const { return _matrix->index2i(*this); }
inline int Matrix::Index::j () const { return _matrix->index2j(*this); }
inline Matrix::Index& Matrix::Index::west () { return _matrix->west (*this); }
inline Matrix::Index& Matrix::Index::east () { return _matrix->east (*this); }
inline Matrix::Index& Matrix::Index::south () { return _matrix->south (*this); }
inline Matrix::Index& Matrix::Index::north () { return _matrix->north (*this); }
} // Anabatic namespace.
inline std::ostream& operator<< ( std::ostream& o, const Anabatic::Matrix::Index& index )
{
o << "(" << index.index() << "|" << index.i() << "," << index.j() << ")";
return o;
}
INSPECTOR_P_SUPPORT(Anabatic::Matrix);
#endif // ANABATIC_MATRIX_H

View File

@ -0,0 +1,55 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/PyAnabaticEngine.h" |
// +-----------------------------------------------------------------+
#ifndef PY_ANABATIC_ENGINE_H
#define PY_ANABATIC_ENGINE_H
#include "hurricane/isobar/PyHurricane.h"
#include "crlcore/PyToolEngine.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyAnabaticEngine".
typedef struct {
CRL::PyToolEngine _baseObject;
} PyAnabaticEngine;
// -------------------------------------------------------------------
// Functions & Types exported to "PyAnabatic.ccp".
extern PyTypeObject PyTypeAnabaticEngine;
extern PyMethodDef PyAnabaticEngine_Methods[];
extern PyObject* PyAnabaticEngine_Link ( Anabatic::AnabaticEngine* );
extern void PyAnabaticEngine_LinkPyType ();
#define IsPyAnabaticEngine(v) ( (v)->ob_type == &PyTypeAnabaticEngine )
#define PYANABATICENGINE(v) ( (PyAnabaticEngine*)(v) )
#define PYANABATICENGINE_O(v) ( PYANABATICENGINE(v)->_baseObject._object )
} // extern "C".
} // Anabatic namespace.
#endif // PY_ANABATIC_ENGINE_H

View File

@ -0,0 +1,53 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/PyGraphicAnabaticEngine.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_PY_GRAPHIC_ANABATIC_ENGINE_H
#define ANABATIC_PY_GRAPHIC_ANABATIC_ENGINE_H
#include "crlcore/PyGraphicToolEngine.h"
#include "anabatic/GraphicAnabaticEngine.h"
namespace Anabatic {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyGraphicAnabaticEngine".
typedef struct {
CRL::PyGraphicTool _baseObject;
} PyGraphicAnabaticEngine;
// -------------------------------------------------------------------
// Functions & Types exported to "PyAnabatic.ccp".
extern PyTypeObject PyTypeGraphicAnabaticEngine;
extern PyMethodDef PyGraphicAnabaticEngine_Methods[];
extern void PyGraphicAnabaticEngine_LinkPyType ();
#define IsPyGraphicAnabaticEngine(v) ( (v)->ob_type == &PyTypeGraphicAnabaticEngine )
#define PY_GRAPHIC_ANABATIC_ENGINE(v) ( (PyGraphicAnabaticEngine*)(v) )
#define PY_GRAPHIC_ANABATIC_ENGINE_O(v) ( PY_GRAPHIC_ANABATIC_ENGINE(v)->_baseObject._object )
} // extern "C".
} // Anabatic namespace.
#endif // ANABATIC_PY_GRAPHIC_ANABATIC_ENGINE_H

View File

@ -19,6 +19,7 @@ projects = [
#, "nimbus"
#, "metis"
#, "mauka"
, "anabatic"
, "knik"
, "katabatic"
, "kite"

View File

@ -9,7 +9,7 @@ try:
import Hurricane
import Viewer
import CRL
#import Anabatic
import Anabatic
import Etesian
import Katabatic
import Kite