Groudwork for short localization in Tramontana.
In order to accurately find the rectangles (Components) causing a short circuit, we need to aggregate the equipotentials as soon as we starts to merge the tiles. Because tiles being a union set, the tree compression forbid to know which tile overlap which one afterwards. So the equipotentials are created early on the fly. We also add an accounting of all the net's components (Plug excluded) to know if it is fully included in the equipotential. If not, we have an open. This is an impacting change from the previous version in which we build the equipotentials *after* aggregating the tiles only. The added cost comes from the number of equipotential merging that we have to perform when we merge tiles. Almost two times slower. May need to have a deep look on how to optimize it later (efficient merge or keeping the order tiles where merged).
This commit is contained in:
parent
5233d860f4
commit
9b87b92eec
|
@ -30,6 +30,7 @@
|
|||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Contact.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Instance.h"
|
||||
|
@ -43,53 +44,6 @@
|
|||
#include "tramontana/TramontanaEngine.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using std::map;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Occurrence;
|
||||
|
||||
|
||||
class NetCompareByName {
|
||||
public:
|
||||
bool operator() ( const Net* lhs, const Net* rhs ) const;
|
||||
};
|
||||
|
||||
|
||||
bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const
|
||||
{
|
||||
if (lhs->isFused () != rhs->isFused ()) return rhs->isFused();
|
||||
if (lhs->isAutomatic() != rhs->isAutomatic()) return rhs->isAutomatic();
|
||||
if (lhs->isGlobal () != rhs->isGlobal ()) return rhs->isGlobal();
|
||||
|
||||
if (lhs->getName().size() != rhs->getName().size())
|
||||
return lhs->getName().size() < rhs->getName().size();
|
||||
return lhs->getName() < rhs->getName();
|
||||
}
|
||||
|
||||
|
||||
class OccNetCompareByName {
|
||||
public:
|
||||
bool operator() ( const Occurrence& lhs, const Occurrence& rhs ) const;
|
||||
};
|
||||
|
||||
|
||||
bool OccNetCompareByName::operator() ( const Occurrence& lhs, const Occurrence& rhs ) const
|
||||
{
|
||||
static NetCompareByName compareByName;
|
||||
|
||||
size_t lhsLength = lhs.getPath().getInstances().getSize();
|
||||
size_t rhsLength = rhs.getPath().getInstances().getSize();
|
||||
|
||||
if (lhsLength != rhsLength) return lhsLength < rhsLength;
|
||||
return compareByName( static_cast<Net*>(lhs.getEntity()), static_cast<Net*>(rhs.getEntity()) );
|
||||
}
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
||||
using std::cout;
|
||||
|
@ -119,6 +73,8 @@ namespace Tramontana {
|
|||
using Hurricane::Layer;
|
||||
using Hurricane::Entity;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Contact;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::RoutingPad;
|
||||
|
@ -127,6 +83,30 @@ namespace Tramontana {
|
|||
using Hurricane::Path;
|
||||
|
||||
|
||||
bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const
|
||||
{
|
||||
if (lhs->isFused () != rhs->isFused ()) return rhs->isFused();
|
||||
if (lhs->isAutomatic() != rhs->isAutomatic()) return rhs->isAutomatic();
|
||||
if (lhs->isGlobal () != rhs->isGlobal ()) return rhs->isGlobal();
|
||||
|
||||
if (lhs->getName().size() != rhs->getName().size())
|
||||
return lhs->getName().size() < rhs->getName().size();
|
||||
return lhs->getName() < rhs->getName();
|
||||
}
|
||||
|
||||
|
||||
bool OccNetCompareByName::operator() ( const Occurrence& lhs, const Occurrence& rhs ) const
|
||||
{
|
||||
static NetCompareByName compareByName;
|
||||
|
||||
size_t lhsLength = lhs.getPath().getInstances().getSize();
|
||||
size_t rhsLength = rhs.getPath().getInstances().getSize();
|
||||
|
||||
if (lhsLength != rhsLength) return lhsLength < rhsLength;
|
||||
return compareByName( static_cast<Net*>(lhs.getEntity()), static_cast<Net*>(rhs.getEntity()) );
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tramontana::Equipotential".
|
||||
|
||||
|
@ -194,19 +174,20 @@ namespace Tramontana {
|
|||
|
||||
|
||||
Equipotential::Equipotential ( Cell* owner )
|
||||
: _owner (owner)
|
||||
, _boundingBox()
|
||||
, _components ()
|
||||
, _childs ()
|
||||
, _name ()
|
||||
, _type (Net::Type::UNDEFINED)
|
||||
, _direction (Net::Direction::DirUndefined)
|
||||
, _netCount (0)
|
||||
, _isBuried (false)
|
||||
, _isExternal (false)
|
||||
, _isGlobal (false)
|
||||
, _isAutomatic(false)
|
||||
, _hasFused (false)
|
||||
: _owner (owner)
|
||||
, _boundingBox ()
|
||||
, _components ()
|
||||
, _childs ()
|
||||
, _name ()
|
||||
, _type (Net::Type::UNDEFINED)
|
||||
, _direction (Net::Direction::DirUndefined)
|
||||
, _netCount (0)
|
||||
, _isBuried (false)
|
||||
, _isExternal (false)
|
||||
, _isGlobal (false)
|
||||
, _isAutomatic (false)
|
||||
, _hasFused (false)
|
||||
, _shortCircuits()
|
||||
{
|
||||
_name = "Unnamed_" + getString( getId() );
|
||||
}
|
||||
|
@ -235,7 +216,9 @@ namespace Tramontana {
|
|||
|
||||
|
||||
Equipotential::~Equipotential ()
|
||||
{ }
|
||||
{
|
||||
for ( ShortCircuit* shortCircuit : _shortCircuits ) delete shortCircuit;
|
||||
}
|
||||
|
||||
|
||||
Cell* Equipotential::getCell () const
|
||||
|
@ -253,7 +236,54 @@ namespace Tramontana {
|
|||
void Equipotential::add ( Occurrence occ, const Box& boundingBox )
|
||||
{
|
||||
if(occ.getPath().isEmpty()) {
|
||||
Contact* contact = dynamic_cast<Contact*>( occ.getEntity() );
|
||||
if ((_components.find(occ) != _components.end())) {
|
||||
if (not contact)
|
||||
cdebug_log(160,0) << "Equipotential::add(): Duplicated " << occ.getCompactString() << endl;
|
||||
return;
|
||||
}
|
||||
Component* comp = dynamic_cast<Component*>( occ.getEntity() );
|
||||
if (not comp) {
|
||||
cerr << Error( "Equipotential::add(): Occurrences with null Path must be Components.\n"
|
||||
" (on:%s)"
|
||||
, getString(occ).c_str()
|
||||
) << endl;
|
||||
return;
|
||||
}
|
||||
cdebug_log(160,0) << "Equipotential::add(): " << occ << endl;
|
||||
_components.insert( occ );
|
||||
NetMap::iterator inet = _nets.find( comp->getNet() );
|
||||
if (inet != _nets.end()) {
|
||||
inet->second.first++;
|
||||
if (inet->second.first > inet->second.second) {
|
||||
cerr << Error( "Equipotential::add(): Doubly counted component of %s.\n"
|
||||
" (on:%s)"
|
||||
, getString(inet->first).c_str()
|
||||
, getString(occ).c_str()
|
||||
) << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
uint32_t compCount = 0;
|
||||
for ( Component* component : comp->getNet()->getComponents() ) {
|
||||
if (dynamic_cast<Plug*>(component)) continue;
|
||||
++compCount;
|
||||
}
|
||||
_nets.insert( make_pair( comp->getNet(), make_pair(1,compCount) ));
|
||||
if (comp->getNet()->isFused()) {
|
||||
_hasFused = true;
|
||||
return;
|
||||
}
|
||||
if (_nets.size() <= 1 + ((_hasFused) ? 1 : 0))
|
||||
return;
|
||||
Net* netA = nullptr;
|
||||
for ( auto item : _nets ) {
|
||||
if (not item.first->isFused() and (item.first != comp->getNet())) {
|
||||
netA = item.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_shortCircuits.push_back( new ShortCircuit( netA, comp->getNet(), comp ));
|
||||
} else {
|
||||
Equipotential* equi = dynamic_cast<Equipotential*>( occ.getEntity() );
|
||||
if (not equi) {
|
||||
|
@ -274,8 +304,7 @@ namespace Tramontana {
|
|||
}
|
||||
_boundingBox.merge( boundingBox );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Equipotential::merge ( Equipotential* other )
|
||||
{
|
||||
if (this == other) {
|
||||
|
@ -285,16 +314,84 @@ namespace Tramontana {
|
|||
) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for ( auto otherNetData : other->_nets ) {
|
||||
NetMap::iterator inet = _nets.find( otherNetData.first );
|
||||
if (inet != _nets.end()) {
|
||||
//inet->second.first += otherNetData.second.first;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (otherNetData.first->isFused()) _hasFused = true;
|
||||
_nets.insert( make_pair( otherNetData.first, make_pair(0,otherNetData.second.second) ));
|
||||
|
||||
if (_nets.size() > 1 + ((_hasFused) ? 1 : 0)) {
|
||||
cdebug_log(169,0) << "Short by merging equis." << _nets.size() << endl;
|
||||
for ( auto inet : _nets ) {
|
||||
cdebug_log(169,0) << "this | " << inet.first << endl;
|
||||
}
|
||||
for ( auto inet : other->_nets ) {
|
||||
cdebug_log(169,0) << "other | " << inet.first << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( const Occurrence& component : other->getComponents() ) add( component );
|
||||
for ( const Occurrence& child : other->getChilds () ) add( child );
|
||||
//cerr << "Equipotential::merge() " << this << endl;
|
||||
//cerr << " " << other << endl;
|
||||
for ( const Occurrence& component : other->getComponents () ) add( component );
|
||||
for ( const Occurrence& child : other->getChilds () ) add( child );
|
||||
for ( ShortCircuit* shortCircuit : other->getShortCircuits () ) add( shortCircuit );
|
||||
_boundingBox.merge( other->_boundingBox );
|
||||
//cerr << "Equipotential::merge() done" << endl;
|
||||
other->clear();
|
||||
}
|
||||
|
||||
|
||||
void Equipotential::consolidate ()
|
||||
{
|
||||
EquipotentialRelation* relation = EquipotentialRelation::create( this );
|
||||
|
||||
|
||||
for ( const Occurrence& occurrence : getComponents() ) {
|
||||
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
|
||||
if (not component) continue;
|
||||
if (not occurrence.getPath().isEmpty()) {
|
||||
//cerr << "Occurrence from a DeepNet " << occurrence << endl;
|
||||
continue;
|
||||
}
|
||||
component->put( relation );
|
||||
}
|
||||
|
||||
if (not _nets.empty()) {
|
||||
_name = getString( (*_nets.begin()).first->getName() );
|
||||
}
|
||||
|
||||
for ( auto netData : _nets ) {
|
||||
Net* net = netData.first;
|
||||
if (net->isFused()) continue;
|
||||
if (net->isExternal ()) _isExternal = true;
|
||||
if (net->isGlobal ()) _isGlobal = true;
|
||||
if (net->isAutomatic()) _isAutomatic = true;
|
||||
_type = net->getType();
|
||||
_direction |= net->getDirection();
|
||||
|
||||
if (netData.second.first >= netData.second.second) {
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
if (dynamic_cast<Plug*>(component)) continue;
|
||||
component->remove( relation );
|
||||
}
|
||||
net->put( relation );
|
||||
}
|
||||
cdebug_log(169,0) << netData.first << " [" << netData.second.first
|
||||
<< " / " << netData.second.second << "]" << endl;
|
||||
}
|
||||
|
||||
for ( Occurrence childEqui : _childs ) {
|
||||
childEqui.put( relation );
|
||||
}
|
||||
if (_components.empty() and _nets.empty()) _isBuried = true;
|
||||
|
||||
#if FIRST_IMPLEMENTATION
|
||||
EquipotentialRelation* relation = EquipotentialRelation::create( this );
|
||||
map<Net*,uint32_t,NetCompareByName> nets;
|
||||
set<Occurrence,OccNetCompareByName> deepNets;
|
||||
|
@ -350,7 +447,7 @@ namespace Tramontana {
|
|||
component->remove( relation );
|
||||
}
|
||||
net->put( relation );
|
||||
_nets.insert( net );
|
||||
//_nets.insert( net );
|
||||
}
|
||||
for ( Occurrence childEqui : _childs ) {
|
||||
childEqui.put( relation );
|
||||
|
@ -359,14 +456,16 @@ namespace Tramontana {
|
|||
|
||||
// if (_name == "abc_11873_auto_rtlil_cc_2560_muxgate_11612")
|
||||
// show();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Equipotential::clear ()
|
||||
{
|
||||
_components.clear();
|
||||
_childs .clear();
|
||||
_nets .clear();
|
||||
_components .clear();
|
||||
_childs .clear();
|
||||
_nets .clear();
|
||||
_shortCircuits.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -391,7 +490,7 @@ namespace Tramontana {
|
|||
sflags += ((_isGlobal ) ? "g" : "-");
|
||||
sflags += ((_isAutomatic) ? "a" : "-");
|
||||
sflags += ((_isBuried ) ? "B" : "-");
|
||||
sflags += " [N:" + getString( _netCount - ((_hasFused) ? 1 : 0) );
|
||||
sflags += " [N:" + getString( _nets.size() - ((_hasFused) ? 1 : 0) );
|
||||
sflags += "+E:" + getString( _childs.size() );
|
||||
if (_hasFused)
|
||||
sflags += "+fused";
|
||||
|
@ -423,7 +522,7 @@ namespace Tramontana {
|
|||
if (record) {
|
||||
record->add( getSlot( "_name" , &_name ) );
|
||||
record->add( getSlot( "_boundingBox", &_boundingBox ) );
|
||||
record->add( getSlot( "_nets" , &_nets ) );
|
||||
//record->add( getSlot( "_nets" , &_nets ) );
|
||||
record->add( getSlot( "_components" , &_components ) );
|
||||
record->add( getSlot( "_childs" , &_childs ) );
|
||||
}
|
||||
|
|
|
@ -185,12 +185,15 @@ namespace Tramontana {
|
|||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
_componentsLocator = nullptr;
|
||||
|
|
|
@ -278,11 +278,13 @@ namespace Tramontana {
|
|||
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
// DebugSession::close();
|
||||
// }
|
||||
cdebug_tabw(160,-1);
|
||||
}
|
||||
//if (debugOn) DebugSession::close();
|
||||
cdebug_tabw(160,-1);
|
||||
//DebugSession::close();
|
||||
mergeEquipotentials();
|
||||
deleteTiles();
|
||||
}
|
||||
|
||||
|
||||
|
@ -322,6 +324,12 @@ namespace Tramontana {
|
|||
}
|
||||
|
||||
|
||||
void SweepLine::deleteTiles ()
|
||||
{
|
||||
Tile::deleteAllTiles();
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::mergeEquipotentials ()
|
||||
{
|
||||
//DebugSession::open( 160, 169 );
|
||||
|
@ -329,7 +337,7 @@ namespace Tramontana {
|
|||
//cerr << "SweepLine::mergeEquipotentials()" << endl;
|
||||
Tile::timeTick();
|
||||
for ( Tile* tile : Tile::getAllTiles() ) {
|
||||
tile->getRoot( Tile::MergeEqui );
|
||||
tile->getRoot( Tile::MergeEqui|Tile::MakeLeafEqui );
|
||||
}
|
||||
cdebug_tabw(160,-1);
|
||||
//DebugSession::close();
|
||||
|
|
|
@ -100,7 +100,10 @@ namespace Tramontana {
|
|||
, _rank (0)
|
||||
, _timeStamp (0)
|
||||
{
|
||||
cdebug_log(160,0) << "Tile::Tile() " << this << endl;
|
||||
_allocateds.push_back( this );
|
||||
if (occurrence.getPath().isEmpty() and not occurrence.getEntity())
|
||||
cerr << "Tile with empty occurrence!!" << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -199,26 +202,79 @@ namespace Tramontana {
|
|||
{ }
|
||||
|
||||
|
||||
void Tile::deleteAllTiles ()
|
||||
{
|
||||
for ( Tile* tile : _allocateds) delete tile;
|
||||
_allocateds.clear();
|
||||
_idCounter = 0;
|
||||
}
|
||||
|
||||
// Net* Tile::getNet () const
|
||||
// { return dynamic_cast<Component*>( _occurrence.getEntity() )->getNet(); }
|
||||
|
||||
|
||||
Tile* Tile::getRoot ( uint32_t flags )
|
||||
{
|
||||
if (not getParent() and (not (flags & MergeEqui))) return this;
|
||||
cdebug_log(160,1) << "Tile::getRoot()" << endl;
|
||||
cdebug_log(160,1) << "Tile::getRoot() tid=" << getId() << " " << getOccurrence() << endl;
|
||||
cdebug_log(160,0) << "+ " << (getEquipotential() ? getString(getEquipotential()) : "equi=NULL") << endl;
|
||||
if (not getParent()) {
|
||||
if ((flags & MakeLeafEqui) and not getEquipotential()) {
|
||||
newEquipotential();
|
||||
}
|
||||
cdebug_tabw(160,-1);
|
||||
return this;
|
||||
}
|
||||
|
||||
Tile* root = this;
|
||||
while ( root->getParent() ) {
|
||||
if (flags & MergeEqui) {
|
||||
if (not root->getParent()->getEquipotential() and root->getEquipotential())
|
||||
root->getParent()->setEquipotential( root->getEquipotential() );
|
||||
}
|
||||
// if (flags & MergeEqui) {
|
||||
// if (not root->getParent()->getEquipotential() and root->getEquipotential()) {
|
||||
// cdebug_log(160,0) << "| tile has no equi, immediate merge" << endl;
|
||||
// root->getParent()->setEquipotential( root->getEquipotential() );
|
||||
// root->getEquipotential()->add( root->getParent()->getOccurrence ()
|
||||
// , root->getParent()->getBoundingBox() );
|
||||
// root->getParent()->setOccMerged( true );
|
||||
// }
|
||||
// }
|
||||
root = root->getParent();
|
||||
cdebug_log(160,0) << "| parent tid=" << root->getId() << " " << root->getOccurrence() << endl;
|
||||
}
|
||||
cdebug_log(160,0) << "> root " << root->getId() << " "
|
||||
cdebug_log(160,0) << "> root tid=" << root->getId() << " "
|
||||
<< (root->getEquipotential() ? getString(root->getEquipotential()) : "equi=NULL") << endl;
|
||||
|
||||
|
||||
if (flags & MergeEqui) {
|
||||
Equipotential* rootEqui = root->getEquipotential();
|
||||
if (not rootEqui) {
|
||||
rootEqui = root->newEquipotential();
|
||||
}
|
||||
|
||||
Tile* current = this;
|
||||
while ((current != root) and current) {
|
||||
if (current->isUpToDate()) {
|
||||
cdebug_log(160,0) << "> Up to date current: tid=" << current->getId() << endl;
|
||||
break;
|
||||
}
|
||||
if (not current->isOccMerged()) {
|
||||
if (current->getEquipotential()) {
|
||||
if (current->getEquipotential() != rootEqui) {
|
||||
cdebug_log(160,0) << "| merge tid=" << current->getId() << " => tid=" << root->getId() << endl;
|
||||
cdebug_log(160,0) << "| tid=" << current->getEquipotential() << endl;
|
||||
rootEqui->merge( current->getEquipotential() );
|
||||
}
|
||||
} else {
|
||||
cdebug_log(160,0) << "| add " << current->getOccurrence() << endl;
|
||||
rootEqui->add( current->getOccurrence(), _boundingBox );
|
||||
}
|
||||
current->setOccMerged( true );
|
||||
current->syncTime();
|
||||
cdebug_log(160,0) << "| current up to date: time=" << current->_timeStamp
|
||||
<< " " << current->isUpToDate() << endl;
|
||||
}
|
||||
current = current->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & Compress) {
|
||||
Tile* current = this;
|
||||
while ( current != root ) {
|
||||
|
@ -228,30 +284,6 @@ namespace Tramontana {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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();
|
||||
current = current->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_tabw(160,-1);
|
||||
return root;
|
||||
}
|
||||
|
@ -259,17 +291,26 @@ namespace Tramontana {
|
|||
|
||||
Tile* Tile::merge ( Tile* other )
|
||||
{
|
||||
Tile* root1 = getRoot();
|
||||
Tile* root2 = other->getRoot();
|
||||
if (root1 and (root1 == root2)) return root1;
|
||||
cdebug_log(160,1) << "Tile::merge() this->tid:" << getId()
|
||||
<< " + other->tid:" << other->getId() << endl;
|
||||
Tile* root1 = getRoot( Compress|MergeEqui );
|
||||
Tile* root2 = other->getRoot( Compress|MergeEqui );
|
||||
if (root1 and (root1 == root2)) {
|
||||
cdebug_log(160,0) << "Already have same root tid:" << root1->getId() << endl;
|
||||
cdebug_tabw(160,-1);
|
||||
return root1;
|
||||
}
|
||||
|
||||
if (root1->getRank() < root2->getRank())
|
||||
std::swap( root1, root2 );
|
||||
if (root1->getRank() == root2->getRank())
|
||||
root1->incRank();
|
||||
root2->setParent( root1 );
|
||||
cdebug_log(160,0) << "New root tid:" << root1->getId()
|
||||
<< " child tid:" << root2->getId() << endl;
|
||||
// Fuse root2 into root1 here!
|
||||
|
||||
cdebug_tabw(160,-1);
|
||||
return root1;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,7 @@ namespace Tramontana {
|
|||
startMeasures();
|
||||
}
|
||||
|
||||
cdebug_log(160,0) << "EXTRACTING " << getCell() << endl;
|
||||
for ( Instance* instance : getCell()->getInstances() ) {
|
||||
Cell* master = instance->getMasterCell();
|
||||
TramontanaEngine* extractor = TramontanaEngine::get( master );
|
||||
|
|
|
@ -44,12 +44,45 @@ namespace Tramontana {
|
|||
using Hurricane::Occurrences;
|
||||
|
||||
|
||||
class NetCompareByName {
|
||||
public:
|
||||
bool operator() ( const Net* lhs, const Net* rhs ) const;
|
||||
};
|
||||
|
||||
|
||||
class OccNetCompareByName {
|
||||
public:
|
||||
bool operator() ( const Occurrence& lhs, const Occurrence& rhs ) const;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tramontana::ShortCircuit".
|
||||
|
||||
class ShortCircuit {
|
||||
public:
|
||||
inline ShortCircuit ( Net*, Net*, Component* );
|
||||
private:
|
||||
Net* _netA;
|
||||
Net* _netB;
|
||||
Component* _shortCircuit;
|
||||
};
|
||||
|
||||
|
||||
inline ShortCircuit::ShortCircuit ( Net* a, Net* b, Component* shortCircuit )
|
||||
: _netA (a)
|
||||
, _netB (b)
|
||||
, _shortCircuit(shortCircuit)
|
||||
{ }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tramontana::Equipotential".
|
||||
|
||||
class Equipotential : public Entity {
|
||||
public:
|
||||
typedef Entity Super;
|
||||
typedef std::map< Net*, std::pair<uint32_t,uint32_t>, NetCompareByName > NetMap;
|
||||
public:
|
||||
static Equipotential* get ( Component* );
|
||||
static Equipotential* get ( Occurrence );
|
||||
|
@ -68,12 +101,15 @@ namespace Tramontana {
|
|||
inline bool hasComponent ( Component* ) const;
|
||||
void add ( Occurrence, const Box& boundingBox=Box() );
|
||||
void merge ( Equipotential* );
|
||||
inline void add ( ShortCircuit* );
|
||||
void consolidate ();
|
||||
void clear ();
|
||||
inline const OccurrenceSet& getComponents () const;
|
||||
inline const OccurrenceSet& getChilds () const;
|
||||
inline const NetSet& getNets () const;
|
||||
inline const NetMap& getNets () const;
|
||||
Occurrences getFlatComponents () const;
|
||||
inline const std::vector<ShortCircuit*>&
|
||||
getShortCircuits () const;
|
||||
Record* _getRecord () const;
|
||||
std::string _getString () const;
|
||||
std::string _getTypeName () const;
|
||||
|
@ -87,32 +123,37 @@ namespace Tramontana {
|
|||
Equipotential ( const Equipotential& ) = delete;
|
||||
Equipotential& operator= ( const Equipotential& ) = delete;
|
||||
private:
|
||||
Cell* _owner;
|
||||
Box _boundingBox;
|
||||
NetSet _nets;
|
||||
OccurrenceSet _components;
|
||||
OccurrenceSet _childs;
|
||||
std::string _name;
|
||||
Net::Type _type;
|
||||
Net::Direction _direction;
|
||||
uint32_t _netCount;
|
||||
bool _isBuried;
|
||||
bool _isExternal;
|
||||
bool _isGlobal;
|
||||
bool _isAutomatic;
|
||||
bool _hasFused;
|
||||
Cell* _owner;
|
||||
Box _boundingBox;
|
||||
NetMap _nets;
|
||||
OccurrenceSet _components;
|
||||
OccurrenceSet _childs;
|
||||
std::string _name;
|
||||
Net::Type _type;
|
||||
Net::Direction _direction;
|
||||
uint32_t _netCount;
|
||||
bool _isBuried;
|
||||
bool _isExternal;
|
||||
bool _isGlobal;
|
||||
bool _isAutomatic;
|
||||
bool _hasFused;
|
||||
std::vector<ShortCircuit*> _shortCircuits;
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline bool Equipotential::isEmpty () const { return _components.empty() and _childs.empty(); }
|
||||
inline bool Equipotential::isBuried () const { return _isBuried; }
|
||||
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::isEmpty () const { return _components.empty() and _childs.empty(); }
|
||||
inline bool Equipotential::isBuried () const { return _isBuried; }
|
||||
inline const OccurrenceSet& Equipotential::getComponents () const { return _components; }
|
||||
inline const OccurrenceSet& Equipotential::getChilds () const { return _childs; }
|
||||
inline const Equipotential::NetMap&
|
||||
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 const std::vector<ShortCircuit*>&
|
||||
Equipotential::getShortCircuits () const { return _shortCircuits; }
|
||||
inline void Equipotential::add ( ShortCircuit* s ) { _shortCircuits.push_back( s ); }
|
||||
|
||||
inline bool Equipotential::hasComponent ( Component* component ) const
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "hurricane/Box.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Occurrence.h"
|
||||
#include "tramontana/Equipotential.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
@ -51,7 +52,6 @@ namespace Tramontana {
|
|||
using Hurricane::GenericFilter;
|
||||
using Hurricane::GenericLocator;
|
||||
using Hurricane::GenericCollection;
|
||||
class Equipotential;
|
||||
|
||||
typedef Hurricane::Locator<Component*> ComponentsLocator;
|
||||
typedef Hurricane::Locator<Occurrence> OccurrencesLocator;
|
||||
|
@ -84,13 +84,13 @@ namespace Tramontana {
|
|||
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;
|
||||
const Equipotential* _equipotential;
|
||||
uint16_t _state;
|
||||
OccurrenceSet::iterator _componentsIterator;
|
||||
Equipotential::NetMap::const_iterator _netsIterator;
|
||||
OccurrenceSet::iterator _childsIterator;
|
||||
OccurrencesLocator* _childCompsLocator;
|
||||
ComponentsLocator* _componentsLocator;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -75,6 +75,7 @@ namespace Tramontana {
|
|||
const LayerSet& getCutConnexLayers ( const BasicLayer* ) const;
|
||||
void run ();
|
||||
void loadTiles ();
|
||||
void deleteTiles ();
|
||||
inline void add ( Tile* );
|
||||
void mergeEquipotentials ();
|
||||
Record* _getRecord () const;
|
||||
|
|
|
@ -52,14 +52,17 @@ namespace Tramontana {
|
|||
|
||||
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);
|
||||
static const uint32_t ForceLayer = (1<<4);
|
||||
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);
|
||||
static const uint32_t MakeLeafEqui = (1<<4);
|
||||
static const uint32_t ForceLayer = (1<<5);
|
||||
static const uint32_t OccMerged = (1<<6);
|
||||
public:
|
||||
static inline const std::vector<Tile*> getAllTiles ();
|
||||
static void deleteAllTiles ();
|
||||
static inline void timeTick ();
|
||||
static Tile* create ( Occurrence
|
||||
, const BasicLayer*
|
||||
|
@ -68,6 +71,7 @@ namespace Tramontana {
|
|||
, uint32_t flags=NoFlags );
|
||||
void destroy ();
|
||||
inline bool isUpToDate () const;
|
||||
inline bool isOccMerged () const;
|
||||
inline unsigned int getId () const;
|
||||
inline uint32_t getRank () const;
|
||||
inline Tile* getParent () const;
|
||||
|
@ -88,6 +92,7 @@ namespace Tramontana {
|
|||
inline void syncTime ();
|
||||
inline void setParent ( Tile* );
|
||||
Tile* merge ( Tile* );
|
||||
inline void setOccMerged ( bool state );
|
||||
inline void setEquipotential ( Equipotential* );
|
||||
Equipotential* newEquipotential ();
|
||||
Record* _getRecord () const;
|
||||
|
@ -117,6 +122,7 @@ 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 bool Tile::isOccMerged () const { return _flags & OccMerged; }
|
||||
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; }
|
||||
|
@ -136,6 +142,10 @@ namespace Tramontana {
|
|||
inline void Tile::setParent ( Tile* parent ) { _parent=parent; }
|
||||
inline void Tile::setEquipotential ( Equipotential* equi ) { _equipotential=equi; }
|
||||
|
||||
inline void Tile::setOccMerged ( bool state )
|
||||
{ if (state) _flags |= OccMerged;
|
||||
else _flags &= ~OccMerged; }
|
||||
|
||||
|
||||
class TileCompare {
|
||||
public:
|
||||
|
|
Loading…
Reference in New Issue