Anabatic transient commit 1.
* New: In Anabatic, basic support for GCell/Edge creation.
This commit is contained in:
parent
f11be897ef
commit
61e9abddbd
|
@ -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)
|
|
@ -0,0 +1 @@
|
|||
install ( FILES FindANABATIC.cmake DESTINATION share/cmake/Modules )
|
|
@ -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)
|
|
@ -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.
|
|
@ -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 )
|
||||
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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;
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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.
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -19,6 +19,7 @@ projects = [
|
|||
#, "nimbus"
|
||||
#, "metis"
|
||||
#, "mauka"
|
||||
, "anabatic"
|
||||
, "knik"
|
||||
, "katabatic"
|
||||
, "kite"
|
||||
|
|
|
@ -9,7 +9,7 @@ try:
|
|||
import Hurricane
|
||||
import Viewer
|
||||
import CRL
|
||||
#import Anabatic
|
||||
import Anabatic
|
||||
import Etesian
|
||||
import Katabatic
|
||||
import Kite
|
||||
|
|
Loading…
Reference in New Issue