From 8f387620cbeeea2a0182c8a16c5bcb3ad80dc7ec Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 18 Mar 2023 18:17:23 +0100 Subject: [PATCH] One Layer, one Cell extraction implementation in Tramontana. * New: Tramontana::Equipotential, implemented. * Change: Tramontana::Tile, add UnionFind capabilities and Equipotential attribute. * New: Tramontana::SweepLine, build upon Hurricane::IntervalTree, can now perform a "one layer only" extraction (checked with "metal1"). --- tramontana/src/CMakeLists.txt | 10 +- tramontana/src/Equipotential.cpp | 189 +++++++++++++++ tramontana/src/PyTramontanaEngine.cpp | 22 ++ tramontana/src/SweepLine.cpp | 166 +++++++++++++ tramontana/src/Tile.cpp | 239 +++++++++++++++++++ tramontana/src/TramontanaEngine.cpp | 26 +- tramontana/src/tramontana/Equipotential.h | 95 ++++++++ tramontana/src/tramontana/SweepLine.h | 100 ++++++++ tramontana/src/tramontana/Tile.h | 142 +++++++++++ tramontana/src/tramontana/TramontanaEngine.h | 10 +- 10 files changed, 993 insertions(+), 6 deletions(-) create mode 100644 tramontana/src/Equipotential.cpp create mode 100644 tramontana/src/SweepLine.cpp create mode 100644 tramontana/src/Tile.cpp create mode 100644 tramontana/src/tramontana/Equipotential.h create mode 100644 tramontana/src/tramontana/SweepLine.h create mode 100644 tramontana/src/tramontana/Tile.h diff --git a/tramontana/src/CMakeLists.txt b/tramontana/src/CMakeLists.txt index 373178f4..abc8f8c5 100644 --- a/tramontana/src/CMakeLists.txt +++ b/tramontana/src/CMakeLists.txt @@ -9,14 +9,20 @@ ${Boost_INCLUDE_DIRS} ${Python_INCLUDE_DIRS} ) - set( includes tramontana/TramontanaEngine.h + set( includes tramontana/Tile.h + tramontana/SweepLine.h + tramontana/Equipotential.h + tramontana/TramontanaEngine.h tramontana/GraphicTramontanaEngine.h ) set( pyIncludes tramontana/PyTramontanaEngine.h tramontana/PyGraphicTramontanaEngine.h ) set( mocIncludes tramontana/GraphicTramontanaEngine.h ) - set( cpps TramontanaEngine.cpp + set( cpps Tile.cpp + SweepLine.cpp + Equipotential.cpp + TramontanaEngine.cpp GraphicTramontanaEngine.cpp ) set( pyCpps PyTramontana.cpp diff --git a/tramontana/src/Equipotential.cpp b/tramontana/src/Equipotential.cpp new file mode 100644 index 00000000..8a1df31c --- /dev/null +++ b/tramontana/src/Equipotential.cpp @@ -0,0 +1,189 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | T r a m o n t a n a - Extractor & LVX | +// | | +// | Algorithm : Christian MASSON | +// | First impl. : Yifei WU | +// | Second impl. : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Equipotential.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/utilities/Path.h" +#include "hurricane/DebugSession.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/Timer.h" +#include "hurricane/Layer.h" +#include "hurricane/Net.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/RoutingPad.h" +#include "crlcore/Utilities.h" +#include "tramontana/Equipotential.h" +#include "tramontana/TramontanaEngine.h" + + +namespace Tramontana { + + using std::cout; + using std::cerr; + using std::endl; + using std::dec; + using std::setw; + using std::setfill; + using std::left; + using std::string; + using std::ostream; + using std::ofstream; + using std::ostringstream; + using std::setprecision; + using std::vector; + using std::make_pair; + using Hurricane::dbo_ptr; + using Hurricane::UpdateSession; + using Hurricane::DebugSession; + using Hurricane::tab; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; + using Hurricane::Box; + using Hurricane::Layer; + using Hurricane::Entity; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::RoutingPad; + using Hurricane::Cell; + using Hurricane::Instance; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::Equipotential". + + + Equipotential::Equipotential ( Cell* owner ) + : _owner (owner) + , _boundingBox() + , _components () + , _childs () + { } + + + void Equipotential::_postCreate () + { + Super::_postCreate(); + TramontanaEngine* tramontana = TramontanaEngine::get( _owner ); + tramontana->add( this ); + } + + + Equipotential* Equipotential::create ( Cell* owner ) + { + Equipotential* equi = new Equipotential ( owner ); + equi->_postCreate(); + return equi; + } + + + void Equipotential::_preDestroy () + { + Super::_preDestroy(); + } + + + Equipotential::~Equipotential () + { } + + + Cell* Equipotential::getCell () const + { return _owner; } + + + Box Equipotential::getBoundingBox () const + { return _boundingBox; } + + + void Equipotential::add ( Component* component ) + { + _components.insert( component ); + } + + + void Equipotential::add ( Occurrence child ) + { + if (child.getPath().isEmpty()) + add( dynamic_cast( child.getEntity() )); + else + _childs.push_back( child ); + } + + + void Equipotential::merge ( Equipotential* other ) + { + if (this == other) { + cerr << Warning( "Equipotential::merge(): Attempt to merge itself (ignored).\n" + " (on: %s)" + , getString(this).c_str() + ) << endl; + return; + } + + for ( Component* component : other->getComponents() ) { + add( component ); + } + for ( Occurrence child : other->getChilds() ) { + add( child ); + } + other->clear(); + } + + + void Equipotential::clear () + { + _components.clear(); + _childs .clear(); + } + + + string Equipotential::_getTypeName () const + { return "Tramontana::Equipotential"; } + + + string Equipotential::_getString () const + { + ostringstream os; + os << "getName() << ">"; + return os.str(); + } + + + Record* Equipotential::_getRecord () const + { + Record* record = new Record ( _getString() ); + if (record) { + record->add( getSlot( "_owner" , &_owner ) ); + record->add( getSlot( "_boundingBox", &_boundingBox ) ); + record->add( getSlot( "_components" , &_components ) ); + record->add( getSlot( "_childs" , &_childs ) ); + } + return record; + } + + +} // Tramontana namespace. diff --git a/tramontana/src/PyTramontanaEngine.cpp b/tramontana/src/PyTramontanaEngine.cpp index 900eed41..11f5a8c8 100644 --- a/tramontana/src/PyTramontanaEngine.cpp +++ b/tramontana/src/PyTramontanaEngine.cpp @@ -140,6 +140,24 @@ extern "C" { } + static PyObject* PyTramontanaEngine_extract ( PyTramontanaEngine* self ) + { + cdebug_log(40,0) << "PyTramontanaEngine_extract()" << endl; + HTRY + METHOD_HEAD("TramontanaEngine.extract()") + if (tramontana->getViewer()) { + if (ExceptionWidget::catchAllWrapper( std::bind(&TramontanaEngine::extract,tramontana) )) { + PyErr_SetString( HurricaneError, "TramontanaEngine::extract() has thrown an exception (C++)." ); + return NULL; + } + } else { + tramontana->extract(); + } + HCATCH + Py_RETURN_NONE; + } + + // Standart Accessors (Attributes). // Standart Destroy (Attribute). @@ -151,8 +169,12 @@ extern "C" { , "Returns the Tramontana engine attached to the Cell, None if there isnt't." } , { "create" , (PyCFunction)PyTramontanaEngine_create , METH_VARARGS|METH_STATIC , "Create a Tramontana engine on this cell." } + , { "destroy" , (PyCFunction)PyTramontanaEngine_destroy , METH_NOARGS + , "Destroy a Tramontana engine." } , { "setViewer" , (PyCFunction)PyTramontanaEngine_setViewer , METH_VARARGS , "Associate a Viewer to this TramontanaEngine." } + , { "extract" , (PyCFunction)PyTramontanaEngine_extract , METH_NOARGS + , "Perform the layout extraction." } , {NULL, NULL, 0, NULL} /* sentinel */ }; diff --git a/tramontana/src/SweepLine.cpp b/tramontana/src/SweepLine.cpp new file mode 100644 index 00000000..8ee8ba09 --- /dev/null +++ b/tramontana/src/SweepLine.cpp @@ -0,0 +1,166 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | T r a m o n t a n a - Extractor & LVX | +// | | +// | Algorithm : Christian MASSON | +// | First impl. : Yifei WU | +// | Second impl. : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./SweepLine.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/utilities/Path.h" +#include "hurricane/DebugSession.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/Timer.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Layer.h" +#include "hurricane/Net.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/RoutingPad.h" +#include "crlcore/Utilities.h" +#include "tramontana/SweepLine.h" + + +namespace Tramontana { + + using std::cout; + using std::cerr; + using std::endl; + using std::dec; + using std::setw; + using std::setfill; + using std::left; + using std::right; + using std::string; + using std::ostream; + using std::ofstream; + using std::ostringstream; + using std::setprecision; + using std::vector; + using std::make_pair; + using Hurricane::dbo_ptr; + using Hurricane::UpdateSession; + using Hurricane::DebugSession; + using Hurricane::tab; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; + using Hurricane::Interval; + using Hurricane::Box; + using Hurricane::DataBase; + using Hurricane::Technology; + using Hurricane::Layer; + using Hurricane::Entity; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::RoutingPad; + using Hurricane::Cell; + using Hurricane::Instance; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::SweepLine". + + + SweepLine::SweepLine ( TramontanaEngine* tramontana ) + : _tramontana (tramontana) + , _tiles () + , _intervalTree() + { } + + + SweepLine::~SweepLine () + { } + + + void SweepLine::run () + { + BasicLayer* layer = DataBase::getDB()->getTechnology()->getBasicLayer( "metal1" ); + loadTiles( layer ); + for ( Element& element : _tiles ) { + Tile* tile = element.getTile(); + TileIntv tileIntv ( tile, tile->getYMin(), tile->getYMax() ); + cerr << right << setw(10) << DbU::getValueString(element.getX()) << " > " << tile << endl; + if (element.isLeftEdge()) { + for ( const TileIntv& overlap : _intervalTree.getOverlaps( + Interval(tile->getYMin(), tile->getYMax() ))) { + cerr << " | intersect " << overlap.getData() << endl; + tile->merge( overlap.getData() ); + } + _intervalTree.insert( tileIntv ); + } else { + _intervalTree.remove( tileIntv ); + } + } + mergeEquipotentials(); + } + + + void SweepLine::loadTiles ( const BasicLayer* layer ) + { + cerr << "SweepLine::run()" << endl; + for ( Occurrence occurrence : getCell()->getOccurrencesUnder( getCell()->getBoundingBox() ) ) { + Component* component = dynamic_cast( occurrence.getEntity() ); + if (not component) continue; + if (not component->getLayer()->contains(layer)) continue; + Tile* tile = Tile::create( occurrence, layer ); + _tiles.push_back( Element( tile, Tile::LeftEdge ) ); + _tiles.push_back( Element( tile, Tile::RightEdge ) ); + } + sort( _tiles.begin(), _tiles.end() ); + } + + + void SweepLine::mergeEquipotentials () + { + Tile::timeTick(); + for ( Tile* tile : Tile::getAllTiles() ) { + tile->getRoot( Tile::MergeEqui ); + } + } + + + string SweepLine::_getTypeName () const + { return "Tramontana::SweepLine"; } + + + string SweepLine::_getString () const + { + ostringstream os; + os << "getCell()->getName() << "\">"; + return os.str(); + } + + + Record* SweepLine::_getRecord () const + { + Record* record = new Record ( _getString() ); + if (record) { + record->add( getSlot( "_tramontana" , &_tramontana ) ); + record->add( getSlot( "_tiles" , &_tiles ) ); + } + return record; + } + + +} // Tramontana namespace. diff --git a/tramontana/src/Tile.cpp b/tramontana/src/Tile.cpp new file mode 100644 index 00000000..e28e8725 --- /dev/null +++ b/tramontana/src/Tile.cpp @@ -0,0 +1,239 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | T r a m o n t a n a - Extractor & LVX | +// | | +// | Algorithm : Christian MASSON | +// | First impl. : Yifei WU | +// | Second impl. : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Tile.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/utilities/Path.h" +#include "hurricane/DebugSession.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/Timer.h" +#include "hurricane/Layer.h" +#include "hurricane/Net.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/RoutingPad.h" +#include "crlcore/Utilities.h" +#include "tramontana/Tile.h" +#include "tramontana/Equipotential.h" + + +namespace Tramontana { + + using std::cout; + using std::cerr; + using std::endl; + using std::dec; + using std::setw; + using std::setfill; + using std::left; + using std::string; + using std::ostream; + using std::ofstream; + using std::ostringstream; + using std::setprecision; + using std::vector; + using std::make_pair; + using Hurricane::dbo_ptr; + using Hurricane::UpdateSession; + using Hurricane::DebugSession; + using Hurricane::tab; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; + using Hurricane::Box; + using Hurricane::Layer; + using Hurricane::Entity; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Hurricane::RoutingPad; + using Hurricane::Cell; + using Hurricane::Instance; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::Tile". + + + uint32_t Tile::_time = 0; + vector Tile::_allocateds; + + + Tile::Tile ( Occurrence occurrence, const BasicLayer* layer, const Box& boundingBox ) + : _occurrence (occurrence) + , _layer (layer) + , _boundingBox (boundingBox) + , _equipotential(nullptr) + , _flags (0) + , _parent (nullptr) + , _rank (0) + , _timeStamp (0) + { + _allocateds.push_back( this ); + } + + + Tile* Tile::create ( Occurrence occurrence, const BasicLayer* layer ) + { + Component* component = dynamic_cast( occurrence.getEntity() ); + if (not component) { + cerr << Error( "Tile::create(): Must be build over an occurrence of *Component*.\n" + " (%s)" + , getString(occurrence).c_str() + ) << endl; + return nullptr; + } + if (not component->getLayer()->contains(layer)) { + cerr << Error( "Tile::create(): Component layer does not contains \"%s\".\n" + " (%s)" + , getString(layer->getName()).c_str() + , getString(occurrence).c_str() + ) << endl; + return nullptr; + } + + Box bb = component->getBoundingBox( layer ); + occurrence.getPath().getTransformation().applyOn( bb ); + Tile* tile = new Tile ( occurrence, layer, bb ); + + return tile; + } + + + void Tile::destroy () + { + cdebug_log(160,1) << "Tile::destroy() " << this << endl; + cdebug_tabw(160,-1); + } + + + Tile::~Tile () + { } + + + Tile* Tile::getRoot ( uint32_t flags ) + { + if (not getParent() and (not (flags & MergeEqui))) return this; + + Tile* root = this; + while ( root->getParent() ) { + if (flags & MergeEqui) { + if (not root->getParent()->getEquipotential() and root->getEquipotential()) + root->getParent()->setEquipotential( root->getEquipotential() ); + } + root = root->getParent(); + } + + if (flags & Compress) { + Tile* current = this; + while ( current != root ) { + Tile* curParent = current->getParent(); + current->setParent( root ); + current = curParent; + } + } + + if (flags & MergeEqui) { + Equipotential* rootEqui = root->getEquipotential(); + if (not rootEqui) + rootEqui = root->newEquipotential(); + + Tile* current = this; + while ( current ) { + if (current->isUpToDate()) break; + if (current->getEquipotential()) { + if (current->getEquipotential() != rootEqui) + rootEqui->merge( current->getEquipotential() ); + } else { + rootEqui->add( current->getOccurrence() ); + } + current->syncTime(); + current = current->getParent(); + } + } + + return root; + } + + + Tile* Tile::merge ( Tile* other ) + { + Tile* root1 = getRoot(); + Tile* root2 = other->getRoot(); + if (root1 and (root1 == root2)) return root1; + + if (root1->getRank() < root2->getRank()) + std::swap( root1, root2 ); + if (root1->getRank() == root2->getRank()) + root1->incRank(); + root2->setParent( root1 ); + // Fuse root2 into root1 here! + + return root1; + } + + + Equipotential* Tile::newEquipotential () + { + if (_equipotential) { + cerr << Error( "Tile::newEquipotential(): Equipotential already created (ignoring).\n" + " (on: %s)" + , getString(this).c_str() + ) << endl; + return _equipotential; + } + + _equipotential = Equipotential::create( _occurrence.getOwnerCell() ); + _equipotential->add( _occurrence ); + return _equipotential; + } + + + string Tile::_getTypeName () const + { return "Tramontana::Tile"; } + + + string Tile::_getString () const + { + ostringstream os; + os << "getName() << " " << _occurrence << ">"; + return os.str(); + } + + + Record* Tile::_getRecord () const + { + Record* record = new Record ( _getString() ); + if (record) { + record->add( getSlot( "_occurrence" , &_occurrence ) ); + record->add( getSlot( "_layer" , _layer ) ); + record->add( getSlot( "_boundingBox", &_boundingBox ) ); + record->add( getSlot( "_flags" , &_flags ) ); + } + return record; + } + + +} // Tramontana namespace. diff --git a/tramontana/src/TramontanaEngine.cpp b/tramontana/src/TramontanaEngine.cpp index 3d09d1a0..629ec10c 100644 --- a/tramontana/src/TramontanaEngine.cpp +++ b/tramontana/src/TramontanaEngine.cpp @@ -41,6 +41,7 @@ #include "crlcore/Measures.h" #include "crlcore/Utilities.h" #include "crlcore/AllianceFramework.h" +#include "tramontana/SweepLine.h" #include "tramontana/TramontanaEngine.h" @@ -100,8 +101,9 @@ namespace Tramontana { TramontanaEngine::TramontanaEngine ( Cell* cell ) - : Super (cell) - , _viewer (NULL) + : Super (cell) + , _viewer (NULL) + , _equipotentials() { } @@ -144,9 +146,29 @@ namespace Tramontana { void TramontanaEngine::extract () { cerr << "TramontanaEngine::extract() called on " << getCell() << endl; + SweepLine sweepLine ( this ); + sweepLine.run(); + showEquipotentials(); } + void TramontanaEngine::showEquipotentials () const + { + cerr << "Equipotentials:" << endl; + for ( Equipotential* equi : _equipotentials ) { + cerr << equi << endl; + for ( Component* component : equi->getComponents() ) { + cerr << "| " << component << endl; + } + } + } + + void TramontanaEngine::add ( Equipotential* equi ) + { + _equipotentials.insert( equi ); + } + + string TramontanaEngine::_getTypeName () const { return "Tramontana::TramontanaEngine"; } diff --git a/tramontana/src/tramontana/Equipotential.h b/tramontana/src/tramontana/Equipotential.h new file mode 100644 index 00000000..672fc866 --- /dev/null +++ b/tramontana/src/tramontana/Equipotential.h @@ -0,0 +1,95 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | T r a m o n t a n a - Extractor & LVX | +// | | +// | Algorithm : Christian MASSON | +// | First impl. : Yifei WU | +// | Second impl. : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./tramontana/Equipotential.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include +#include +#include "hurricane/Component.h" +#include "hurricane/Occurrence.h" +namespace Hurricane { + class Net; +} + + +namespace Tramontana { + + using Hurricane::Record; + using Hurricane::Box; + using Hurricane::DbU; + using Hurricane::DBo; + using Hurricane::Entity; + using Hurricane::Layer; + using Hurricane::BasicLayer; + using Hurricane::Net; + using Hurricane::Cell; + using Hurricane::Component; + using Hurricane::Occurrence; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::Equipotential". + + class Equipotential : public Entity { + public: + typedef Entity Super; + typedef std::set ComponentSet; + public: + static Equipotential* create ( Cell* ); + inline bool isEmpty () const; + virtual Cell* getCell () const; + virtual Box getBoundingBox () const; + inline bool hasComponent ( Component* ) const; + void add ( Component* ); + void add ( Occurrence ); + void merge ( Equipotential* ); + void clear (); + inline const ComponentSet& getComponents () const; + inline const std::vector& getChilds () const; + Record* _getRecord () const; + std::string _getString () const; + std::string _getTypeName () const; + protected: + virtual void _postCreate (); + virtual void _preDestroy (); + private: + Equipotential ( Cell* ); + ~Equipotential (); + private: + Equipotential ( const Equipotential& ) = delete; + Equipotential& operator= ( const Equipotential& ) = delete; + private: + Cell* _owner; + Box _boundingBox; + ComponentSet _components; + std::vector _childs; + }; + + + + inline bool Equipotential::isEmpty () const { return _components.empty() and _childs.empty(); } + inline const Equipotential::ComponentSet& Equipotential::getComponents () const { return _components; } + inline const std::vector& Equipotential::getChilds () const { return _childs; } + + inline bool Equipotential::hasComponent ( Component* component ) const + { return _components.find( component ) != _components.end(); } + + +} // Tramontana namespace. + + +INSPECTOR_P_SUPPORT(Tramontana::Equipotential); diff --git a/tramontana/src/tramontana/SweepLine.h b/tramontana/src/tramontana/SweepLine.h new file mode 100644 index 00000000..1e3b441d --- /dev/null +++ b/tramontana/src/tramontana/SweepLine.h @@ -0,0 +1,100 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | T r a m o n t a n a - Extractor & LVX | +// | | +// | Algorithm : Christian MASSON | +// | First impl. : Yifei WU | +// | Second impl. : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./tramontana/SweepLine.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include +#include +#include "hurricane/BasicLayer.h" +namespace Hurricane { + class Net; +} +#include "tramontana/Tile.h" +#include "tramontana/TramontanaEngine.h" + + +namespace Tramontana { + + using Hurricane::Record; + using Hurricane::Box; + using Hurricane::DbU; + using Hurricane::Cell; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::SweepLine". + + class SweepLine { + private: + class Element { + public: + inline Element ( Tile*, uint32_t flags ); + inline bool operator< ( const Element& ) const; + inline bool isLeftEdge () const; + inline Tile* getTile () const; + inline DbU::Unit getX () const; + inline DbU::Unit getY () const; + inline DbU::Unit getId () const; + private: + Tile* _tile; + uint32_t _flags; + }; + public: + SweepLine ( TramontanaEngine* ); + ~SweepLine (); + inline Cell* getCell (); + void run (); + void loadTiles ( const BasicLayer* ); + void mergeEquipotentials (); + Record* _getRecord () const; + std::string _getString () const; + std::string _getTypeName () const; + private: + SweepLine ( const SweepLine& ) = delete; + SweepLine& operator= ( const SweepLine& ) = delete; + private: + TramontanaEngine* _tramontana; + std::vector _tiles; + TileIntvTree _intervalTree; + }; + + +// SweepLine::Element. + inline SweepLine::Element::Element ( Tile* tile, uint32_t flags ) : _tile(tile), _flags(flags) { } + inline bool SweepLine::Element::isLeftEdge () const { return _flags & Tile::LeftEdge; } + inline Tile* SweepLine::Element::getTile () const { return _tile; } + inline DbU::Unit SweepLine::Element::getX () const { return isLeftEdge() ? _tile->getLeftEdge() : _tile->getRightEdge(); } + inline DbU::Unit SweepLine::Element::getY () const { return _tile->getBoundingBox().getYMin(); } + inline DbU::Unit SweepLine::Element::getId () const { return _tile->getId(); } + + inline bool SweepLine::Element::operator< ( const Element& rhs ) const + { + if (getX() != rhs.getX()) return (getX() < rhs.getX()); + if (getY() != rhs.getY()) return (getY() < rhs.getY()); + return getId() < rhs.getId(); + } + + +// SweepLine. + inline Cell* SweepLine::getCell () { return _tramontana->getCell(); } + + + +} // Tramontana namespace. + + +INSPECTOR_P_SUPPORT(Tramontana::SweepLine); diff --git a/tramontana/src/tramontana/Tile.h b/tramontana/src/tramontana/Tile.h new file mode 100644 index 00000000..652d346a --- /dev/null +++ b/tramontana/src/tramontana/Tile.h @@ -0,0 +1,142 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | T r a m o n t a n a - Extractor & LVX | +// | | +// | Algorithm : Christian MASSON | +// | First impl. : Yifei WU | +// | Second impl. : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./tramontana/Tile.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include +#include +#include "hurricane/Box.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Component.h" +#include "hurricane/Occurrence.h" +#include "hurricane/IntervalTree.h" +namespace Hurricane { + class Net; +} + + +namespace Tramontana { + + using Hurricane::Record; + using Hurricane::Box; + using Hurricane::DbU; + using Hurricane::Layer; + using Hurricane::BasicLayer; + using Hurricane::Net; + using Hurricane::Cell; + using Hurricane::Component; + using Hurricane::Occurrence; + using Hurricane::RbTree; + using Hurricane::IntervalData; + using Hurricane::IntervalTree; + class Equipotential; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::Tile". + + class Tile { + public: + static const uint32_t NoFlags = 0; + static const uint32_t LeftEdge = (1<<0); + static const uint32_t RightEdge = (1<<1); + static const uint32_t Compress = (1<<2); + static const uint32_t MergeEqui = (1<<3); + public: + static inline const std::vector getAllTiles (); + static inline void timeTick (); + static Tile* create ( Occurrence, const BasicLayer* ); + void destroy (); + inline bool isUpToDate () const; + inline unsigned int getId () const; + inline uint32_t getRank () const; + inline Tile* getParent () const; + Tile* getRoot ( uint32_t flags=Compress ); + inline Component* getComponent () const; + inline Occurrence getOccurrence () const; + inline const BasicLayer* getLayer () const; + inline const Box& getBoundingBox () const; + inline Equipotential* getEquipotential () const; + inline DbU::Unit getLeftEdge () const; + inline DbU::Unit getRightEdge () const; + inline DbU::Unit getYMin () const; + inline DbU::Unit getYMax () const; + inline uint32_t getFlags () const; + inline void incRank (); + inline void syncTime (); + inline void setParent ( Tile* ); + Tile* merge ( Tile* ); + inline void setEquipotential ( Equipotential* ); + Equipotential* newEquipotential (); + Record* _getRecord () const; + std::string _getString () const; + std::string _getTypeName () const; + private: + Tile ( Occurrence, const BasicLayer*, const Box& ); + ~Tile (); + private: + Tile ( const Tile& ) = delete; + Tile& operator= ( const Tile& ) = delete; + private: + static uint32_t _time; + static std::vector _allocateds; + Occurrence _occurrence; + const BasicLayer* _layer; + Box _boundingBox; + Equipotential* _equipotential; + uint32_t _flags; + Tile* _parent; + uint32_t _rank; + uint32_t _timeStamp; + }; + + inline const std::vector Tile::getAllTiles () { return _allocateds; } + inline void Tile::timeTick () { _time++; } + inline bool Tile::isUpToDate () const { return _timeStamp >= _time; } + inline unsigned int Tile::getId () const { return getComponent()->getId(); } + inline Component* Tile::getComponent () const { return dynamic_cast( _occurrence.getEntity() ); } + inline Occurrence Tile::getOccurrence () const { return _occurrence; } + inline const BasicLayer* Tile::getLayer () const { return _layer; } + inline const Box& Tile::getBoundingBox () const { return _boundingBox; } + inline Equipotential* Tile::getEquipotential () const { return _equipotential; } + inline DbU::Unit Tile::getLeftEdge () const { return _boundingBox.getXMin(); } + inline DbU::Unit Tile::getRightEdge () const { return _boundingBox.getXMax(); } + inline DbU::Unit Tile::getYMin () const { return _boundingBox.getYMin(); } + inline DbU::Unit Tile::getYMax () const { return _boundingBox.getYMax(); } + inline uint32_t Tile::getFlags () const { return _flags; } + inline uint32_t Tile::getRank () const { return _rank; } + inline Tile* Tile::getParent () const { return _parent; } + inline void Tile::incRank () { _rank++; } + inline void Tile::syncTime () { _timeStamp=_time; } + inline void Tile::setParent ( Tile* parent ) { _parent=parent; } + inline void Tile::setEquipotential ( Equipotential* equi ) { _equipotential=equi; } + + +// ------------------------------------------------------------------- +// Class : "Tramontana::TileIntvTree". + + + typedef IntervalData TileIntv; + typedef IntervalTree TileIntvTree; + + +} // Tramontana namespace. + + +INSPECTOR_P_SUPPORT(Tramontana::Tile); +INSPECTOR_PR_SUPPORT(Tramontana::TileIntv); +INSPECTOR_PR_SUPPORT(Tramontana::TileIntvTree); diff --git a/tramontana/src/tramontana/TramontanaEngine.h b/tramontana/src/tramontana/TramontanaEngine.h index a0dc3642..46212665 100644 --- a/tramontana/src/tramontana/TramontanaEngine.h +++ b/tramontana/src/tramontana/TramontanaEngine.h @@ -27,6 +27,7 @@ namespace Hurricane { class CellViewer; } #include "crlcore/ToolEngine.h" +#include "tramontana/Equipotential.h" namespace Tramontana { @@ -53,15 +54,19 @@ namespace Tramontana { public: const Name& getName () const; inline void setViewer ( CellViewer* ); + inline CellViewer* getViewer (); void extract (); + void showEquipotentials () const; + void add ( Equipotential* ); virtual Record* _getRecord () const; virtual std::string _getString () const; virtual std::string _getTypeName () const; private: // Attributes. static Name _toolName; - protected: + private: CellViewer* _viewer; + std::set _equipotentials; protected: // Constructors & Destructors. TramontanaEngine ( Cell* ); @@ -74,7 +79,8 @@ namespace Tramontana { }; - inline void TramontanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } + inline void TramontanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } + inline CellViewer* TramontanaEngine::getViewer () { return _viewer; } } // Tramontana namespace.