coriolis/tramontana/src/EquipotentialComponents.cpp

246 lines
7.8 KiB
C++
Raw Normal View History

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.
2023-04-13 07:00:50 -05:00
// -*- 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 _netsIterator->first->isFused()
and _netsIterator->first->getProperty(EquipotentialRelation::staticGetName())) {
if (not _componentsLocator) {
_componentsLocator = _netsIterator->first->getComponents().getLocator()->getClone();
if (_componentsLocator->isValid()) return;
} else {
_componentsLocator->progress();
if (_componentsLocator->isValid()) return;
}
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.
2023-04-13 07:00:50 -05:00
}
_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.