From 9b87b92eec154a1d4877e242d513c191932f0795 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 16 Jun 2023 13:34:36 +0200 Subject: [PATCH] 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). --- tramontana/src/Equipotential.cpp | 241 ++++++++++++------ tramontana/src/EquipotentialComponents.cpp | 15 +- tramontana/src/SweepLine.cpp | 10 +- tramontana/src/Tile.cpp | 109 +++++--- tramontana/src/TramontanaEngine.cpp | 1 + tramontana/src/tramontana/Equipotential.h | 87 +++++-- .../src/tramontana/EquipotentialComponents.h | 16 +- tramontana/src/tramontana/SweepLine.h | 1 + tramontana/src/tramontana/Tile.h | 22 +- 9 files changed, 353 insertions(+), 149 deletions(-) diff --git a/tramontana/src/Equipotential.cpp b/tramontana/src/Equipotential.cpp index d5a49b65..e4a25b02 100644 --- a/tramontana/src/Equipotential.cpp +++ b/tramontana/src/Equipotential.cpp @@ -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(lhs.getEntity()), static_cast(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(lhs.getEntity()), static_cast(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( 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( 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(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( 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( 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(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 nets; set 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 ) ); } diff --git a/tramontana/src/EquipotentialComponents.cpp b/tramontana/src/EquipotentialComponents.cpp index 6c4470b9..2b5fb566 100644 --- a/tramontana/src/EquipotentialComponents.cpp +++ b/tramontana/src/EquipotentialComponents.cpp @@ -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; diff --git a/tramontana/src/SweepLine.cpp b/tramontana/src/SweepLine.cpp index 5a6f51f3..317e4b23 100644 --- a/tramontana/src/SweepLine.cpp +++ b/tramontana/src/SweepLine.cpp @@ -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(); diff --git a/tramontana/src/Tile.cpp b/tramontana/src/Tile.cpp index 45e0d5a2..e6863ae4 100644 --- a/tramontana/src/Tile.cpp +++ b/tramontana/src/Tile.cpp @@ -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( _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; } diff --git a/tramontana/src/TramontanaEngine.cpp b/tramontana/src/TramontanaEngine.cpp index 2786e232..8b028520 100644 --- a/tramontana/src/TramontanaEngine.cpp +++ b/tramontana/src/TramontanaEngine.cpp @@ -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 ); diff --git a/tramontana/src/tramontana/Equipotential.h b/tramontana/src/tramontana/Equipotential.h index fefecd6b..1f699663 100644 --- a/tramontana/src/tramontana/Equipotential.h +++ b/tramontana/src/tramontana/Equipotential.h @@ -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, 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& + 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 _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& + Equipotential::getShortCircuits () const { return _shortCircuits; } + inline void Equipotential::add ( ShortCircuit* s ) { _shortCircuits.push_back( s ); } inline bool Equipotential::hasComponent ( Component* component ) const { diff --git a/tramontana/src/tramontana/EquipotentialComponents.h b/tramontana/src/tramontana/EquipotentialComponents.h index 70967612..ae502891 100644 --- a/tramontana/src/tramontana/EquipotentialComponents.h +++ b/tramontana/src/tramontana/EquipotentialComponents.h @@ -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 ComponentsLocator; typedef Hurricane::Locator 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: diff --git a/tramontana/src/tramontana/SweepLine.h b/tramontana/src/tramontana/SweepLine.h index a7a4aec9..4ab04e98 100644 --- a/tramontana/src/tramontana/SweepLine.h +++ b/tramontana/src/tramontana/SweepLine.h @@ -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; diff --git a/tramontana/src/tramontana/Tile.h b/tramontana/src/tramontana/Tile.h index 2d2a3e20..6414719e 100644 --- a/tramontana/src/tramontana/Tile.h +++ b/tramontana/src/tramontana/Tile.h @@ -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 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::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( _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: