Full transhierarchical implementation done.

* New: Equipotential elements includes now:
    1. Components at the top level (the cell owning the Equi).
    2. Nets at the top level. If an equi include all the components
       of a Net, own the Net, not all it's individual components.
    3. Other equipotentials from the Instances immediatey below.
       Thoses equis should be equivalents to the Plug of the Net.
       They are stored in the form of Occurrences <Instance,Equi>,
       the relation is stored on that Occurrence.
* New: Equipotential::getFlatComponents(), a collection to recursively
    get all the *component* occurrences of the equi. Transhierarchically.
    Go through components, nets components, and recursively through
    the child equis.
* New: EquipotentialRelation, the master of this relation is the
    Equipotential and the slaves, all its elements.
* Change: In Tile, in case the tile is build on a deep component,
    we trace up the Equipotential it belongs to in the Instance
    level immediately belonging to the Cell under extraction.
    They must exists as we extract from bottom to top all the
    master cells. So we have, for that tile an Occurrence
    <Instance,Equi> that we can store in the current Equi level.
* Change/Bug: In Tile, add an Id to be reliably sort the tiles
    in the IntervalTree. As we replaced the tile component occurrence
    by a <Instance,Equi> we were having multiple tiles with the same
    equi. This was causing havoc again in the IntervalTree.
      Should add a check in the RbTree for elements with the
    exact same key, but that would imply passing a new template
    parameter for the "equal" function.
This commit is contained in:
Jean-Paul Chaput 2023-04-13 14:00:50 +02:00
parent 57bab117b4
commit c3bed61257
14 changed files with 589 additions and 70 deletions

View File

@ -14,6 +14,7 @@
tramontana/SweepLine.h
tramontana/Equipotential.h
tramontana/EquipotentialRelation.h
tramontana/EquipotentialComponents.h
tramontana/TramontanaEngine.h
tramontana/GraphicTramontanaEngine.h
)
@ -30,6 +31,7 @@
SweepLine.cpp
Equipotential.cpp
EquipotentialRelation.cpp
EquipotentialComponents.cpp
TramontanaEngine.cpp
GraphicTramontanaEngine.cpp
EquipotentialsModel.cpp

View File

@ -18,6 +18,7 @@
#include <iomanip>
#include <set>
#include <map>
#include "hurricane/utilities/Path.h"
#include "hurricane/DebugSession.h"
#include "hurricane/UpdateSession.h"
@ -38,12 +39,15 @@
#include "crlcore/Utilities.h"
#include "tramontana/Equipotential.h"
#include "tramontana/EquipotentialRelation.h"
#include "tramontana/EquipotentialComponents.h"
#include "tramontana/TramontanaEngine.h"
namespace {
using std::map;
using Hurricane::Net;
using Hurricane::Plug;
using Hurricane::Occurrence;
@ -120,13 +124,73 @@ namespace Tramontana {
using Hurricane::RoutingPad;
using Hurricane::Cell;
using Hurricane::Instance;
using Hurricane::Path;
// -------------------------------------------------------------------
// Class : "Tramontana::Equipotential".
const char* defaultName = "Unamed (please call consolidate())";
Equipotential* Equipotential::get ( Component* component )
{
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>(
component->getNet()->getProperty( EquipotentialRelation::staticGetName() ));
if (not relation) {
relation = dynamic_cast<EquipotentialRelation*>(
component->getProperty( EquipotentialRelation::staticGetName() ));
}
if (not relation) return nullptr;
return dynamic_cast<Equipotential*>( relation->getMasterOwner() );
}
Equipotential* Equipotential::get ( Occurrence occurrence )
{
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>(
occurrence.getProperty( EquipotentialRelation::staticGetName() ));
if (not relation) return nullptr;
return dynamic_cast<Equipotential*>( relation->getMasterOwner() );
}
Occurrence Equipotential::getChildEqui ( Occurrence flatOccurrence )
{
Component* component = dynamic_cast<Component*>( flatOccurrence.getEntity() );
if (not component) {
cerr << Error( "Equipotential::getChildEqui(): Occurrence must be over a Component.\n"
" (on:%s)"
, getString(flatOccurrence).c_str()
) << endl;
return Occurrence();
}
Equipotential* equi = Equipotential::get( component );
if (not equi) {
cerr << Error( "Equipotential::getChildEqui(): Component not associated to an Equipotential.\n"
" (on:%s)"
, getString(flatOccurrence).c_str()
) << endl;
return Occurrence();
}
if (flatOccurrence.getPath().isEmpty()) return flatOccurrence;
// cerr << "childEqui:" << flatOccurrence << endl;
// cerr << " " << equi << endl;
Instance* tailInst = flatOccurrence.getPath().getTailInstance();
Path headPath = flatOccurrence.getPath().getHeadPath();
Occurrence tailOccurrence;
while ( tailInst ) {
tailOccurrence = Occurrence( equi, tailInst );
equi = Equipotential::get( tailOccurrence );
tailInst = headPath.getTailInstance();
headPath = headPath.getHeadPath();
}
// cerr << " ==> " << tailOccurrence << endl;
// cerr << " " << equi << endl;
return tailOccurrence;
}
Equipotential::Equipotential ( Cell* owner )
@ -134,7 +198,7 @@ namespace Tramontana {
, _boundingBox()
, _components ()
, _childs ()
, _name (defaultName)
, _name ()
, _type (Net::Type::UNDEFINED)
, _direction (Net::Direction::DirUndefined)
, _netCount (0)
@ -142,7 +206,9 @@ namespace Tramontana {
, _isGlobal (false)
, _isAutomatic(false)
, _hasFused (false)
{ }
{
_name = "Unnamed_" + getString( getId() );
}
void Equipotential::_postCreate ()
@ -178,10 +244,33 @@ namespace Tramontana {
Box Equipotential::getBoundingBox () const
{ return _boundingBox; }
Occurrences Equipotential::getFlatComponents () const
{ return EquipotentialComponents( this ); }
void Equipotential::add ( Occurrence component, const Box& boundingBox )
void Equipotential::add ( Occurrence occ, const Box& boundingBox )
{
_components.insert( component );
if(occ.getPath().isEmpty()) {
_components.insert( occ );
} else {
Equipotential* equi = dynamic_cast<Equipotential*>( occ.getEntity() );
if (not equi) {
cerr << Error( "Equipotential::add(): Occurrence is not an Equipotential.\n"
" (on:%s)"
, getString(occ).c_str()
) << endl;
return;
}
if (not occ.getPath().getTailPath().isEmpty()) {
cerr << Error( "Equipotential::add(): Occurrence is more than one instances deep.\n"
" (on:%s)"
, getString(occ).c_str()
) << endl;
return;
}
_childs.insert( occ );
}
_boundingBox.merge( boundingBox );
}
@ -206,7 +295,7 @@ namespace Tramontana {
void Equipotential::consolidate ()
{
EquipotentialRelation* relation = EquipotentialRelation::create( this );
set<Net*,NetCompareByName> nets;
map<Net*,uint32_t,NetCompareByName> nets;
set<Occurrence,OccNetCompareByName> deepNets;
for ( const Occurrence& occurrence : getComponents() ) {
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
@ -225,10 +314,15 @@ namespace Tramontana {
_type = net->getType();
_direction |= net->getDirection();
}
nets.insert( component->getNet() );
uint32_t accounted = (dynamic_cast<Plug*>(component)) ? 0 : 1;
auto inet = nets.find( component->getNet() );
if (inet != nets.end())
inet->second += accounted;
else
nets.insert( make_pair( component->getNet(), accounted ) );
}
if (not nets.empty()) {
_name = getString( (*nets.begin())->getName() );
_name = getString( (*nets.begin()).first->getName() );
} else {
if (not deepNets.empty()) {
_name = (*deepNets.begin()).getCompactString();
@ -236,6 +330,31 @@ namespace Tramontana {
}
_netCount = nets.size();
for ( auto item : nets ) {
Net* net = item.first;
uint32_t count = 0;
for ( Component* component : net->getComponents() ) {
count += (dynamic_cast<Plug*>(component)) ? 0 : 1;
}
if (count > item.second) continue;
if (count < item.second) {
cerr << Error( "Equipotential::consolidate(): On %s, found more components of %s than existing (%d > %d)."
, getString(this).c_str()
, getString(net).c_str()
, item.second
, count ) << endl;
}
for ( Component* component : net->getComponents() ) {
if (dynamic_cast<Plug*>(component)) continue;
component->remove( relation );
}
net->put( relation );
_nets.insert( net );
}
for ( Occurrence childEqui : _childs ) {
childEqui.put( relation );
}
// if (_name == "abc_11873_auto_rtlil_cc_2560_muxgate_11612")
// show();
}
@ -245,6 +364,7 @@ namespace Tramontana {
{
_components.clear();
_childs .clear();
_nets .clear();
}
@ -268,7 +388,8 @@ namespace Tramontana {
sflags += ((_isExternal ) ? "e" : "-");
sflags += ((_isGlobal ) ? "g" : "-");
sflags += ((_isAutomatic) ? "a" : "-");
sflags += " [" + getString( _netCount - ((_hasFused) ? 1 : 0) );
sflags += " [N:" + getString( _netCount - ((_hasFused) ? 1 : 0) );
sflags += "+E:" + getString( _childs.size() );
if (_hasFused)
sflags += "+fused";
sflags += "] ";
@ -295,13 +416,13 @@ namespace Tramontana {
Record* Equipotential::_getRecord () const
{
Record* record = new Record ( _getString() );
Record* record = Super::_getRecord();
if (record) {
record->add( getSlot( "_owner" , &_owner ) );
record->add( getSlot( "_name" , &_name ) );
record->add( getSlot( "_boundingBox", &_boundingBox ) );
record->add( getSlot( "_nets" , &_nets ) );
record->add( getSlot( "_components" , &_components ) );
record->add( getSlot( "_childs" , &_childs ) );
//record->add( getSlot( "_name" , &_name ) );
}
return record;
}

View File

@ -0,0 +1,242 @@
// -*- 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 : "./EquipotentialComponents.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "tramontana/EquipotentialComponents.h"
#include "tramontana/Equipotential.h"
namespace Tramontana {
using namespace std;
using Hurricane::tab;
using Hurricane::Error;
using Hurricane::Path;
// -------------------------------------------------------------------
// Class : "Tramontana::EquipotentialComponents".
EquipotentialComponents::EquipotentialComponents ()
: Super()
, _equipotential(nullptr)
{ }
EquipotentialComponents::EquipotentialComponents ( const Equipotential* equi )
: Super()
, _equipotential(equi)
{ }
EquipotentialComponents::EquipotentialComponents ( const EquipotentialComponents& other )
: Super()
, _equipotential(other._equipotential)
{ }
EquipotentialComponents& EquipotentialComponents::operator= ( const EquipotentialComponents& other )
{
_equipotential = other._equipotential;
return *this;
}
Collection<Occurrence>* EquipotentialComponents::getClone () const
{ return new EquipotentialComponents( *this ); }
Locator<Occurrence>* EquipotentialComponents::getLocator () const
{ return new Locator ( _equipotential ); }
string EquipotentialComponents::_getString () const
{
string s = "<EquipotentialComponents ";
if (_equipotential) {
s += " " + getString( _equipotential );
} else {
s += " NULL";
}
s += ">";
return s;
}
// -------------------------------------------------------------------
// Class : "Tramontana::EquipotentialComponents::Locator".
EquipotentialComponents::Locator::Locator ()
: Super()
, _equipotential (nullptr)
, _state (Constructed)
, _componentsIterator()
, _netsIterator ()
, _childsIterator ()
, _childCompsLocator (nullptr)
, _componentsLocator (nullptr)
{ }
EquipotentialComponents::Locator::Locator ( const Equipotential* equi )
: Super()
, _equipotential (equi)
, _state (Constructed)
, _componentsIterator(equi->getComponents().end())
, _netsIterator (equi->getNets().end())
, _childsIterator (equi->getChilds().end())
, _childCompsLocator (nullptr)
, _componentsLocator (nullptr)
{
progress();
}
EquipotentialComponents::Locator::Locator ( const Locator& other )
: Super()
, _equipotential (other._equipotential)
, _state (other._state)
, _componentsIterator(other._componentsIterator)
, _netsIterator (other._netsIterator)
, _childsIterator (other._childsIterator)
, _childCompsLocator (nullptr)
, _componentsLocator (nullptr)
{
if (other._childCompsLocator) _childCompsLocator = other._childCompsLocator->getClone();
if (other._componentsLocator) _componentsLocator = other._componentsLocator->getClone();
}
EquipotentialComponents::Locator& EquipotentialComponents::Locator::operator= ( const Locator& other )
{
_equipotential = other._equipotential;
_state = other._state;
_componentsIterator= other._componentsIterator;
_netsIterator = other._netsIterator;
_childsIterator = other._childsIterator;
_componentsLocator = (other._componentsLocator) ? other._componentsLocator->getClone() : nullptr;
_childCompsLocator = (other._childCompsLocator) ? other._childCompsLocator->getClone() : nullptr;
return *this;
}
Occurrence EquipotentialComponents::Locator::getElement () const
{
if (not _equipotential or (_state >= Finished)) return Occurrence();
switch ( _state ) {
case InComponents: return (*_componentsIterator);
case InNets: return Occurrence( _componentsLocator->getElement() );
case InChildEquis: {
Path compPath = (*_childsIterator).getPath();
Path tailPath = _childCompsLocator->getElement().getPath();
while ( not tailPath.isEmpty() ) {
compPath = Path( compPath, tailPath.getHeadInstance() );
tailPath = tailPath.getTailPath();
}
return Occurrence( _childCompsLocator->getElement().getEntity(), compPath );
}
default:
break;
}
return Occurrence();
}
Locator<Occurrence>* EquipotentialComponents::Locator::getClone () const
{ return new Locator( *this ); }
bool EquipotentialComponents::Locator::isValid () const
{ return (_equipotential) and (_state < Finished); }
void EquipotentialComponents::Locator::progress ()
{
while ( isValid() ) {
switch ( _state ) {
case Constructed: {
_state = InComponents;
_componentsIterator = _equipotential->getComponents().begin();
if (_componentsIterator != _equipotential->getComponents().end()) return;
}
case InComponents: {
if (_componentsIterator != _equipotential->getComponents().end()) {
++_componentsIterator;
if (_componentsIterator != _equipotential->getComponents().end()) return;
}
_state = InNets;
_netsIterator = _equipotential->getNets().begin();
}
case InNets: {
if (_netsIterator != _equipotential->getNets().end()) {
if (not _componentsLocator) {
_componentsLocator = (*_netsIterator)->getComponents().getLocator()->getClone();
if (_componentsLocator->isValid()) return;
} else {
_componentsLocator->progress();
if (_componentsLocator->isValid()) return;
}
_componentsLocator = nullptr;
++_netsIterator;
if (_netsIterator != _equipotential->getNets().end())
continue;
}
_state = InChildEquis;
_childsIterator = _equipotential->getChilds().begin();
}
case InChildEquis: {
if (_childsIterator != _equipotential->getChilds().end()) {
if (not _childCompsLocator) {
Equipotential* child = dynamic_cast<Equipotential*>( (*_childsIterator).getEntity() );
_childCompsLocator = child->getFlatComponents().getLocator()->getClone();
if (_childCompsLocator->isValid()) return;
} else {
_childCompsLocator->progress();
if (_childCompsLocator->isValid()) return;
}
_childCompsLocator = nullptr;
++_childsIterator;
if (_childsIterator != _equipotential->getChilds().end())
continue;
}
_state = Finished;
}
case Finished:
break;
}
}
}
string EquipotentialComponents::Locator::_getString () const
{
string s = "<EquipotentialComponents::Locator";
if (_equipotential) {
s += " " + getString(_equipotential);
} else {
s += " NULL";
}
s += ">";
return s;
}
} // Tramontana namespace.

View File

@ -17,6 +17,7 @@
#include "tramontana/EquipotentialRelation.h"
#include "tramontana/TramontanaEngine.h"
namespace Tramontana {
@ -48,6 +49,10 @@ namespace Tramontana {
{ Super::_preDestroy(); }
Name EquipotentialRelation::staticGetName ()
{ return EquipotentialRelationName; }
Name EquipotentialRelation::getName () const
{ return EquipotentialRelationName; }

View File

@ -154,10 +154,10 @@ namespace Tramontana {
switch ( isel->getAccesses() ) {
case 1: break;
case 64:
emit equipotentialSelect ( isel->getEqui()->getComponents() );
emit equipotentialSelect ( isel->getEqui()->getFlatComponents() );
break;
case 0:
emit equipotentialUnselect ( isel->getEqui()->getComponents() );
emit equipotentialUnselect ( isel->getEqui()->getFlatComponents() );
remove = isel;
++isel;
_selecteds.erase( remove );

View File

@ -92,7 +92,8 @@ namespace Tramontana {
for ( const BasicLayer* bl : DataBase::getDB()->getTechnology()->getBasicLayers() ) {
// HARDCODED. Should read the gauge.
if (getString(bl->getName()).substr(0,6) == "gmetal") continue;
if (bl->getMaterial() == BasicLayer::Material::metal)
if ( (bl->getMaterial() == BasicLayer::Material::metal)
or (bl->getMaterial() == BasicLayer::Material::poly))
_extracteds.push_back( bl );
}
@ -142,7 +143,7 @@ namespace Tramontana {
continue;
}
if (element.isLeftEdge()) {
// if (tile->getId() == 60117) {
// if (tile->getId() == 46055) {
// DebugSession::open( 0, 169 );
// if (not written) intvTree->second.write( "tree-before.gv" );
// cdebug_log(160,0) << " Interval tree *before* insertion." << endl;
@ -166,7 +167,7 @@ namespace Tramontana {
// cerr << " | insert " << tile << endl;
// }
intvTree->second.insert( tileIntv );
// if (tile->getId() == 60117) {
// if (tile->getId() == 46055) {
// if (not written) intvTree->second.write( "tree-after.gv" );
// written = true;
// DebugSession::close();
@ -188,9 +189,9 @@ namespace Tramontana {
// }
cdebug_log(160,0) << " | remove tile" << endl;
intvTree->second.remove( tileIntv );
//DebugSession::open( 0, 169 );
intvTree->second.checkVMax();
//DebugSession::close();
// DebugSession::open( 0, 169 );
// intvTree->second.checkVMax();
// DebugSession::close();
// if ((tile->getId() == 289) and not written) {
// //DebugSession::open( 0, 169 );
// written = true;
@ -216,7 +217,7 @@ namespace Tramontana {
// }
// }
}
intvTree->second.checkVMax();
//intvTree->second.checkVMax();
cdebug_tabw(160,-1);
}
//if (debugOn) DebugSession::close();
@ -264,11 +265,15 @@ namespace Tramontana {
void SweepLine::mergeEquipotentials ()
{
//DebugSession::open( 160, 169 );
cdebug_log(160,1) << "SweepLine::mergeEquipotentials()" << endl;
//cerr << "SweepLine::mergeEquipotentials()" << endl;
Tile::timeTick();
for ( Tile* tile : Tile::getAllTiles() ) {
tile->getRoot( Tile::MergeEqui );
}
cdebug_tabw(160,-1);
//DebugSession::close();
}

View File

@ -96,14 +96,14 @@ namespace Tramontana {
getCellWidget()->closeRefreshSession ();
}
getCellWidget()->setShowSelection( true );
connect( _browser, SIGNAL(equipotentialSelect (const OccurrenceSet&)), getCellWidget(), SLOT(selectSet (const OccurrenceSet&)) );
connect( _browser, SIGNAL(equipotentialUnselect(const OccurrenceSet&)), getCellWidget(), SLOT(unselectSet(const OccurrenceSet&)) );
connect( _browser, SIGNAL(equipotentialSelect (Occurrences)), getCellWidget(), SLOT(select (Occurrences)) );
connect( _browser, SIGNAL(equipotentialUnselect(Occurrences)), getCellWidget(), SLOT(unselect(Occurrences)) );
_browser->updateSelecteds();
} else {
getCellWidget()->setShowSelection( false );
getCellWidget()->setCumulativeSelection( _cwCumulativeSelection );
_browser->disconnect( getCellWidget(), SLOT(selectSet (const OccurrenceSet&)) );
_browser->disconnect( getCellWidget(), SLOT(unselectSet(const OccurrenceSet&)) );
_browser->disconnect( getCellWidget(), SLOT(select (Occurrences)) );
_browser->disconnect( getCellWidget(), SLOT(unselect(Occurrences)) );
}
}

View File

@ -77,12 +77,14 @@ namespace Tramontana {
// Class : "Tramontana::Tile".
uint32_t Tile::_time = 0;
uint32_t Tile::_idCounter = 0;
uint32_t Tile::_time = 0;
vector<Tile*> Tile::_allocateds;
Tile::Tile ( Occurrence occurrence, const BasicLayer* layer, const Box& boundingBox )
: _occurrence (occurrence)
: _id (_idCounter++)
, _occurrence (occurrence)
, _layer (layer)
, _boundingBox (boundingBox)
, _equipotential(nullptr)
@ -116,6 +118,9 @@ namespace Tramontana {
Box bb = component->getBoundingBox( layer );
occurrence.getPath().getTransformation().applyOn( bb );
if (not occurrence.getPath().isEmpty())
occurrence = Equipotential::getChildEqui( occurrence );
Tile* tile = new Tile ( occurrence, layer, bb );
return tile;
@ -133,8 +138,8 @@ namespace Tramontana {
{ }
Net* Tile::getNet () const
{ return dynamic_cast<Component*>( _occurrence.getEntity() )->getNet(); }
// Net* Tile::getNet () const
// { return dynamic_cast<Component*>( _occurrence.getEntity() )->getNet(); }
Tile* Tile::getRoot ( uint32_t flags )
@ -150,7 +155,8 @@ namespace Tramontana {
}
root = root->getParent();
}
cdebug_log(160,0) << "> root " << root->getId() << endl;
cdebug_log(160,0) << "> root " << root->getId() << " "
<< (root->getEquipotential() ? getString(root->getEquipotential()) : "equi=NULL") << endl;
if (flags & Compress) {
Tile* current = this;
@ -173,9 +179,11 @@ namespace Tramontana {
if (current->getEquipotential()) {
if (current->getEquipotential() != rootEqui) {
cdebug_log(160,0) << "| merge " << current->getId() << " => " << root->getId() << endl;
cdebug_log(160,0) << "| " << current->getEquipotential() << endl;
rootEqui->merge( current->getEquipotential() );
}
} else {
cdebug_log(160,0) << "| add " << current->getOccurrence() << endl;
rootEqui->add( current->getOccurrence(), _boundingBox );
}
current->syncTime();
@ -217,8 +225,8 @@ namespace Tramontana {
_equipotential = Equipotential::create( _occurrence.getOwnerCell() );
_equipotential->add( _occurrence, _boundingBox );
//cerr << "new " << _equipotential << endl;
//cerr << "| " << _occurrence << endl;
cdebug_log(160,0) << "new " << _equipotential << endl;
cdebug_log(160,0) << "| " << _occurrence << endl;
return _equipotential;
}

View File

@ -235,7 +235,7 @@ namespace Tramontana {
Record* record = Super::_getRecord ();
if (record) {
//record->add( getSlot( "_blocks" , &_blocks ) );
record->add( getSlot( "_equipotentials", &_equipotentials ) );
}
return record;
}

View File

@ -22,6 +22,8 @@
#include "hurricane/Net.h"
#include "hurricane/Component.h"
#include "hurricane/Occurrence.h"
#include "hurricane/Occurrences.h"
#include "tramontana/EquipotentialRelation.h"
namespace Tramontana {
@ -34,10 +36,12 @@ namespace Tramontana {
using Hurricane::Layer;
using Hurricane::BasicLayer;
using Hurricane::Net;
using Hurricane::NetSet;
using Hurricane::Cell;
using Hurricane::Component;
using Hurricane::OccurrenceSet;
using Hurricane::Occurrence;
using Hurricane::Occurrences;
// -------------------------------------------------------------------
@ -47,37 +51,44 @@ namespace Tramontana {
public:
typedef Entity Super;
public:
static Equipotential* create ( Cell* );
inline bool isEmpty () const;
virtual Cell* getCell () const;
virtual Box getBoundingBox () const;
inline std::string getName () const;
std::string getFlagsAsString () const;
inline Net::Type getType () const;
inline Net::Direction getDirection () const;
void show () const;
inline bool hasComponent ( Component* ) const;
void add ( Occurrence, const Box& boundingBox=Box() );
void merge ( Equipotential* );
void consolidate ();
void clear ();
inline const OccurrenceSet& getComponents () const;
inline const OccurrenceSet& 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;
static Equipotential* get ( Component* );
static Equipotential* get ( Occurrence );
static Occurrence getChildEqui ( Occurrence );
public:
static Equipotential* create ( Cell* );
inline bool isEmpty () const;
virtual Cell* getCell () const;
virtual Box getBoundingBox () const;
inline std::string getName () const;
std::string getFlagsAsString () const;
inline Net::Type getType () const;
inline Net::Direction getDirection () const;
void show () const;
inline bool hasComponent ( Component* ) const;
void add ( Occurrence, const Box& boundingBox=Box() );
void merge ( Equipotential* );
void consolidate ();
void clear ();
inline const OccurrenceSet& getComponents () const;
inline const OccurrenceSet& getChilds () const;
inline const NetSet& getNets () const;
Occurrences getFlatComponents () 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;
NetSet _nets;
OccurrenceSet _components;
OccurrenceSet _childs;
std::string _name;
@ -95,12 +106,23 @@ namespace Tramontana {
inline bool Equipotential::isEmpty () const { return _components.empty() and _childs.empty(); }
inline const OccurrenceSet& Equipotential::getComponents () const { return _components; }
inline const OccurrenceSet& Equipotential::getChilds () const { return _childs; }
inline const NetSet& Equipotential::getNets () const { return _nets; }
inline std::string Equipotential::getName () const { return _name; }
inline Net::Type Equipotential::getType () const { return _type; }
inline Net::Direction Equipotential::getDirection () const { return _direction; }
inline bool Equipotential::hasComponent ( Component* component ) const
{ return _components.find( Occurrence(component) ) != _components.end(); }
{
if (component->getCell() != getCell()) return false;
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>(
component->getNet()->getProperty( EquipotentialRelation::staticGetName() ));
if (not relation) {
relation = dynamic_cast<EquipotentialRelation*>(
component->getProperty( EquipotentialRelation::staticGetName() ));
}
if (not relation) return false;
return (relation->getMasterOwner() == this);
}
} // Tramontana namespace.

View File

@ -0,0 +1,110 @@
// -*- 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/EquipotentialComponents.h" |
// +-----------------------------------------------------------------+
#pragma once
#include <string>
#include <list>
#include <vector>
#include <array>
#include <map>
#include "hurricane/Collection.h"
#include "hurricane/DbU.h"
#include "hurricane/Box.h"
#include "hurricane/Net.h"
#include "hurricane/Occurrence.h"
namespace Tramontana {
using std::string;
using std::pair;
using std::list;
using std::vector;
using std::map;
using Hurricane::Record;
using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Entity;
using Hurricane::Component;
using Hurricane::Net;
using Hurricane::NetSet;
using Hurricane::Occurrence;
using Hurricane::OccurrenceSet;
using Hurricane::Filter;
using Hurricane::Locator;
using Hurricane::Collection;
using Hurricane::GenericFilter;
using Hurricane::GenericLocator;
using Hurricane::GenericCollection;
class Equipotential;
typedef Hurricane::Locator<Component*> ComponentsLocator;
typedef Hurricane::Locator<Occurrence> OccurrencesLocator;
// -------------------------------------------------------------------
// Class : "Tramontana::EquipotentialComponents".
class EquipotentialComponents : public Collection<Occurrence> {
public:
typedef Collection<Occurrence> Super;
static const uint16_t Constructed = (1<<0);
static const uint16_t InComponents = (1<<1);
static const uint16_t InNets = (1<<2);
static const uint16_t InChildEquis = (1<<3);
static const uint16_t Finished = (1<<4);
public:
class Locator : public Hurricane::Locator<Occurrence> {
public:
typedef Hurricane::Locator<Occurrence> Super;
public:
Locator ();
Locator ( const Equipotential* );
Locator ( const Locator& );
Locator& operator= ( const Locator& );
virtual Occurrence getElement () const;
virtual Hurricane::Locator<Occurrence>*
getClone () const;
virtual bool isValid () const;
virtual void progress ();
virtual std::string _getString () const;
private:
const Equipotential* _equipotential;
uint16_t _state;
OccurrenceSet::iterator _componentsIterator;
NetSet::iterator _netsIterator;
OccurrenceSet::iterator _childsIterator;
OccurrencesLocator* _childCompsLocator;
ComponentsLocator* _componentsLocator;
};
public:
EquipotentialComponents ();
EquipotentialComponents ( const Equipotential* );
EquipotentialComponents ( const EquipotentialComponents& );
EquipotentialComponents& operator= ( const EquipotentialComponents& );
virtual Collection<Occurrence>* getClone () const;
virtual Hurricane::Locator<Occurrence>* getLocator () const;
virtual std::string _getString () const;
private:
const Equipotential* _equipotential;
};
} // Tramontana namespace.

View File

@ -18,7 +18,6 @@
#pragma once
#include "hurricane/Relation.h"
#include "tramontana/TramontanaEngine.h"
namespace Tramontana {
@ -26,6 +25,8 @@ namespace Tramontana {
using Hurricane::Name;
using Hurricane::Record;
using Hurricane::Relation;
using Hurricane::Component;
class Equipotential;
// -------------------------------------------------------------------
@ -37,6 +38,7 @@ namespace Tramontana {
public:
static EquipotentialRelation* get ( const Component* );
static EquipotentialRelation* create ( Equipotential* );
static Name staticGetName ();
public:
virtual Name getName () const;
virtual std::string _getTypeName () const;

View File

@ -137,8 +137,8 @@ namespace Tramontana {
void goTo ( int );
void updateSelecteds ();
signals:
void equipotentialSelect ( const OccurrenceSet& );
void equipotentialUnselect ( const OccurrenceSet& );
void equipotentialSelect ( Occurrences );
void equipotentialUnselect ( Occurrences );
void reframe ( const Box& );
private slots:
void textFilterChanged ();

View File

@ -66,9 +66,9 @@ namespace Tramontana {
inline uint32_t getRank () const;
inline Tile* getParent () const;
Tile* getRoot ( uint32_t flags=Compress );
inline Component* getComponent () const;
//inline Component* getComponent () const;
inline Occurrence getOccurrence () const;
Net* getNet () const;
// Net* getNet () const;
inline Layer::Mask getMask () const;
inline const BasicLayer* getLayer () const;
inline const Box& getBoundingBox () const;
@ -94,8 +94,10 @@ namespace Tramontana {
Tile ( const Tile& ) = delete;
Tile& operator= ( const Tile& ) = delete;
private:
static uint32_t _idCounter;
static uint32_t _time;
static std::vector<Tile*> _allocateds;
uint32_t _id;
Occurrence _occurrence;
const BasicLayer* _layer;
Box _boundingBox;
@ -109,8 +111,8 @@ namespace Tramontana {
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 unsigned int Tile::getId () const { return _id; }
//inline Component* Tile::getComponent () const { return dynamic_cast<Component*>( _occurrence.getEntity() ); }
inline Occurrence Tile::getOccurrence () const { return _occurrence; }
inline Layer::Mask Tile::getMask () const { return _layer->getMask(); }
inline const BasicLayer* Tile::getLayer () const { return _layer; }
@ -134,7 +136,7 @@ namespace Tramontana {
inline bool operator() ( const Tile* lhs, const Tile* rhs ) const
{
cdebug_log(0,0) << "TileCompare::operator()" << std::endl;
return lhs->getOccurrence() < rhs->getOccurrence();
return lhs->getId() < rhs->getId();
}
};