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").
This commit is contained in:
Jean-Paul Chaput 2023-03-18 18:17:23 +01:00
parent 5879a5b581
commit 8f387620cb
10 changed files with 993 additions and 6 deletions

View File

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

View File

@ -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 <iomanip>
#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<Component*>( 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 << "<Equipotential id:" << getId() << " " << _owner->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.

View File

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

View File

@ -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 <iomanip>
#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<Component*>( 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 << "<SweepLine \"" << _tramontana->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.

239
tramontana/src/Tile.cpp Normal file
View File

@ -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 <iomanip>
#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*> 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<Component*>( 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 << "<Tile " << _boundingBox << " " << _layer->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.

View File

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

View File

@ -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 <iostream>
#include <vector>
#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<Component*,DBo::CompareById> 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<Occurrence>& 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<Occurrence> _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<Occurrence>& 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);

View File

@ -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 <iostream>
#include <vector>
#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<Element> _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);

View File

@ -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 <iostream>
#include <vector>
#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<Tile*> 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<Tile*> _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*> 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<Component*>( _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<Tile*> TileIntv;
typedef IntervalTree<Tile*> TileIntvTree;
} // Tramontana namespace.
INSPECTOR_P_SUPPORT(Tramontana::Tile);
INSPECTOR_PR_SUPPORT(Tramontana::TileIntv);
INSPECTOR_PR_SUPPORT(Tramontana::TileIntvTree);

View File

@ -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<Equipotential*,DBo::CompareById> _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.