diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 267fd03d..274636f0 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -883,8 +883,8 @@ namespace Etesian { Cell* masterCell = instance->getMasterCell(); string instanceName = occurrence.getCompactString(); // Remove the enclosing brackets... - instanceName.erase( 0, 1 ); - instanceName.erase( instanceName.size()-1 ); + //instanceName.erase( 0, 1 ); + //instanceName.erase( instanceName.size()-1 ); if (CatalogExtension::isFeed(masterCell)) { string feedName = getString( instance->getName() ); @@ -1557,8 +1557,8 @@ namespace Etesian { Instance* instance = static_cast(occurrence.getEntity()); string instanceName = occurrence.getCompactString(); // Remove the enclosing brackets... - instanceName.erase( 0, 1 ); - instanceName.erase( instanceName.size()-1 ); + //instanceName.erase( 0, 1 ); + //instanceName.erase( instanceName.size()-1 ); auto iid = _instsToIds.find( instance ); if (iid == _instsToIds.end() ) { diff --git a/hurricane/src/hurricane/Commons.cpp b/hurricane/src/hurricane/Commons.cpp index fed4c301..fb4d0a50 100644 --- a/hurricane/src/hurricane/Commons.cpp +++ b/hurricane/src/hurricane/Commons.cpp @@ -36,7 +36,7 @@ namespace Hurricane { #ifdef HAVE_CXA_DEMANGLE string demangle ( const char* symbol ) -{ +{ int status; size_t length = 4096; char demangled[length]; @@ -49,13 +49,25 @@ string demangle ( const char* symbol ) #else string demangle ( const char* symbol ) -{ - return symbol; -} +{ return symbol; } #endif + string& split ( string& s ) + { + size_t i = s.find( "<" ); + while ( i != string::npos ) { + if (i+3 > s.size()) break; + //if (s[i+2] != '>') { + s.insert( i, "\\n" ); + //} + i = s.find( "<", i+3 ); + } + return s; + } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Interval.cpp b/hurricane/src/hurricane/Interval.cpp index cd338d5a..7581b471 100644 --- a/hurricane/src/hurricane/Interval.cpp +++ b/hurricane/src/hurricane/Interval.cpp @@ -111,21 +111,21 @@ bool Interval::intersect(const Interval& interval, bool strict) const if (isEmpty() or interval.isEmpty()) return false; if ( (_vMax < interval._vMin) or (interval._vMax < _vMin) ) return false; - return not strict or ( (_vMax != interval._vMin) and (interval._vMax != _vMin) ); + return not strict or ( (_vMax > interval._vMin) or (interval._vMax > _vMin) ); } bool Interval::inferior(const Interval& interval, bool strict) const // ***************************************************************** { - if (_vMax < interval._vMin) return true; - return not strict and (_vMax == interval._vMin); + if (_vMax == interval._vMin) return not strict; + return (_vMax < interval._vMin); } bool Interval::superior(const Interval& interval, bool strict) const // ***************************************************************** { if (_vMin > interval._vMax) return true; - return !strict && (_vMin == interval._vMax); + return not (strict or (_vMin != interval._vMax)); } bool Interval::isConstrainedBy(const Interval& interval) const diff --git a/hurricane/src/hurricane/Occurrence.cpp b/hurricane/src/hurricane/Occurrence.cpp index 49cb3456..67e3750f 100644 --- a/hurricane/src/hurricane/Occurrence.cpp +++ b/hurricane/src/hurricane/Occurrence.cpp @@ -96,16 +96,27 @@ bool Occurrence::operator!=(const Occurrence& occurrence) const bool Occurrence::operator<(const Occurrence& occurrence) const // ******************************************************** { - if (not _entity and not occurrence._entity) return false; - if (not _entity) return true; - if (not occurrence._entity) return false; + cdebug_log(0,0) << "Occurrence::operator<()" << endl; + cdebug_log(0,0) << "| lhs=" << *this << endl; + cdebug_log(0,0) << "| rhs=" << occurrence << endl; + if ((not _sharedPath) xor (not occurrence._sharedPath)) return not _sharedPath; + if ((not _entity ) xor (not occurrence._entity )) return not _entity; + if (_entity and (_entity->getId() != occurrence._entity->getId())) + return _entity->getId() < occurrence._entity->getId(); + if (not _sharedPath) return false; - if (_entity->getId() < occurrence._entity->getId()) return true; - if (_entity->getId() > occurrence._entity->getId()) return false; + // if (not _sharedPath) return true; + // if (not occurrence._sharedPath) return false; + // if (not _sharedPath and not occurrence._sharedPath) return false; + // if (not _sharedPath) return true; + // if (not occurrence._sharedPath) return false; - if (not _sharedPath and not occurrence._sharedPath) return false; - if (not _sharedPath) return true; - if (not occurrence._sharedPath) return false; + // if (not _entity and not occurrence._entity) return false; + // if (not _entity) return true; + // if (not occurrence._entity) return false; + + // if (_entity->getId() < occurrence._entity->getId()) return true; + // if (_entity->getId() > occurrence._entity->getId()) return false; return _sharedPath->getHash() < occurrence._sharedPath->getHash(); @@ -274,7 +285,7 @@ string Occurrence::_getString() const string Occurrence::getCompactString() const // **************************************** { - string s = "<"; + string s; if (_entity) { s += getString(getOwnerCell()->getName()); s += ":"; @@ -291,7 +302,6 @@ string Occurrence::getCompactString() const } } } - s += ">"; return s; } diff --git a/hurricane/src/hurricane/hurricane/Commons.h b/hurricane/src/hurricane/hurricane/Commons.h index 9f0489ff..8c5ecbe5 100644 --- a/hurricane/src/hurricane/hurricane/Commons.h +++ b/hurricane/src/hurricane/hurricane/Commons.h @@ -146,6 +146,9 @@ namespace Hurricane { } + string& split ( std::string& ); + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/IntervalTree.h b/hurricane/src/hurricane/hurricane/IntervalTree.h index 20c55536..d104d117 100644 --- a/hurricane/src/hurricane/hurricane/IntervalTree.h +++ b/hurricane/src/hurricane/hurricane/IntervalTree.h @@ -55,6 +55,7 @@ namespace Hurricane { inline Data& getData () const; inline DbU::Unit getChildsVMax () const; inline DbU::Unit updateChildsVMax ( DbU::Unit lvmax, DbU::Unit rvmax ); + inline bool operator== ( const IntervalData& ) const; string _getString () const; Record* _getRecord () const; private: @@ -62,7 +63,7 @@ namespace Hurricane { Data data_; }; - + template< typename Data > inline IntervalData::IntervalData () : Interval(1,-1) @@ -91,9 +92,19 @@ namespace Hurricane { template< typename Data > inline DbU::Unit IntervalData::updateChildsVMax ( DbU::Unit lvmax, DbU::Unit rvmax ) - { childsVMax_ = std::max( getVMax(), std::max( lvmax, rvmax ) ); return childsVMax_; } + { + cdebug_log(0,0) << "IntervalData::updateChildsVMax() " << DbU::getValueString(lvmax) + << " " << DbU::getValueString(lvmax) + << " " << this << endl; + childsVMax_ = std::max( getVMax(), std::max( lvmax, rvmax ) ); return childsVMax_; + } + + template< typename Data > + inline bool IntervalData::operator== ( const IntervalData& other ) const + { return Interval::operator==(*this) and (data_ == other.data_); } + template< typename Data > std::string IntervalData::_getString () const { @@ -116,13 +127,34 @@ namespace Hurricane { } +// ------------------------------------------------------------------- +// Class : "Hurricane::IntervalDataCompare". + + template< typename Data, typename DataCompare=std::less > + class IntervalDataCompare { + public: + inline bool operator() ( const IntervalData& lhs, const IntervalData& rhs ) const + { + static Interval::CompareByMinMax compare; + static DataCompare dataCompare; + if ( (lhs.getVMin() == rhs.getVMin()) + and (lhs.getVMax() == rhs.getVMax())) { + cdebug_log(0,0) << "IntervalDataCompare::operator<() - Data fallback." << endl; + cdebug_log(0,0) << "| " << lhs.getData() << endl; + return dataCompare( lhs.getData(), rhs.getData() ); + } + return compare( lhs, rhs ); + } + }; + + // ------------------------------------------------------------------- // Class : "Hurricane::IntervalTree". - template< typename Data > - class IntervalTree : public RbTree< IntervalData, Interval::CompareByMinMax > { + template< typename Data, typename DataCompare=std::less > + class IntervalTree : public RbTree< IntervalData, IntervalDataCompare > { public: - typedef RbTree< IntervalData, Interval::CompareByMinMax > Super; + typedef RbTree< IntervalData, IntervalDataCompare > Super; public: class overlap_iterator : public Super::iterator { public: @@ -169,32 +201,39 @@ namespace Hurricane { size_t getThickness () const; overlap_iterator beginOverlaps ( const Interval& ) const; inline OverlapElements getOverlaps ( const Interval& ) const; + void checkVMax () const; + void checkVMax ( typename Super::Node* node ) const; private: inline void updateChildsVMax ( typename Super::Node* ); }; - template< typename Data > - IntervalTree::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap ) + template< typename Data, typename DataCompare > + IntervalTree::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap ) : Super::iterator(node) , overlap_(overlap) - { } - - - template< typename Data > - typename IntervalTree::overlap_iterator& IntervalTree::overlap_iterator::operator++ () { + cdebug_log(0,0) << "IntervalTree::overlap_iterator CTOR " + << (node ? ::getString(node->getValue()) : "node=NULL") + << " " << overlap << endl; + } + + + template< typename Data, typename DataCompare > + typename IntervalTree::overlap_iterator& + IntervalTree::overlap_iterator::operator++ () + { + cdebug_log(0,0) << "IntervalTree::overlap_iterator::operator++()" << endl; while ( true ) { Super::iterator::operator++(); if (not this->isValid()) break; - cdebug_log(0,0) << "IntervalTree::overlap_iterator::operator++() " - << ::getString(this->getNode()) << std::endl; + cdebug_log(0,0) << " ==> " << ::getString(this->getNode()->getValue()) << std::endl; - if (this->getNode()->getValue().intersect(overlap_,true)) break; - cdebug_log(0,0) << "NO intersections" << endl; - if (overlap_.inferior(this->getNode()->getValue(),true)) { - cdebug_log(0,0) << "Node is inferior, stop here." << endl; + if (this->getNode()->getValue().intersect(overlap_,false)) break; + cdebug_log(0,0) << " NO intersections" << endl; + if (overlap_.inferior(this->getNode()->getValue(),false)) { + cdebug_log(0,0) << " Node is inferior, stop here." << endl; this->setNode( NULL ); break; } @@ -207,44 +246,45 @@ namespace Hurricane { // Class : "Hurricane::IntervalTree::OverlapOverlapElements" (implementation) - template< typename Data > - inline IntervalTree::OverlapElements::Locator::Locator ( const Locator &locator ) + template< typename Data, typename DataCompare > + inline IntervalTree::OverlapElements::Locator::Locator ( const Locator &locator ) : Hurricane::Locator< IntervalData >() , iterator_(locator.iterator_) { } - template< typename Data > - IntervalTree::OverlapElements::Locator::Locator ( const IntervalTree& tree, const Interval& span ) + template< typename Data, typename DataCompare > + IntervalTree::OverlapElements::Locator::Locator ( const IntervalTree& tree, const Interval& span ) : Hurricane::Locator< IntervalData >() , iterator_(tree.beginOverlaps(span)) { } - template< typename Data > - typename IntervalTree::OverlapElements::Locator* IntervalTree::OverlapElements::Locator::getClone () const + template< typename Data, typename DataCompare > + typename IntervalTree::OverlapElements::Locator* + IntervalTree::OverlapElements::Locator::getClone () const { return new Locator(*this); } - template< typename Data > - IntervalData IntervalTree::OverlapElements::Locator::getElement () const + template< typename Data, typename DataCompare > + IntervalData IntervalTree::OverlapElements::Locator::getElement () const { return (*iterator_); } - template< typename Data > - bool IntervalTree::OverlapElements::Locator::isValid () const + template< typename Data, typename DataCompare > + bool IntervalTree::OverlapElements::Locator::isValid () const { return iterator_.isValid(); } - template< typename Data > - void IntervalTree::OverlapElements::Locator::progress () + template< typename Data, typename DataCompare > + void IntervalTree::OverlapElements::Locator::progress () { if (isValid()) ++iterator_; } - template< typename Data > - std::string IntervalTree::OverlapElements::Locator::_getString () const + template< typename Data, typename DataCompare > + std::string IntervalTree::OverlapElements::Locator::_getString () const { std::string s = "<" + _TName("OverlapElements::Locator") + ">"; @@ -252,34 +292,34 @@ namespace Hurricane { } - template< typename Data > - inline IntervalTree::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span ) + template< typename Data, typename DataCompare > + inline IntervalTree::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span ) : Collection< IntervalData >() , tree_(tree) , span_(span) { } - template< typename Data > - inline IntervalTree::OverlapElements::OverlapElements ( const OverlapElements& elements ) + template< typename Data, typename DataCompare > + inline IntervalTree::OverlapElements::OverlapElements ( const OverlapElements& elements ) : Collection< IntervalData >() , tree_(elements.tree_) , span_(elements.span_) { } - template< typename Data > - Collection< IntervalData >* IntervalTree::OverlapElements::getClone () const + template< typename Data, typename DataCompare > + Collection< IntervalData >* IntervalTree::OverlapElements::getClone () const { return new OverlapElements(*this); } - template< typename Data > - typename IntervalTree::OverlapElements::Locator* IntervalTree::OverlapElements::getLocator () const + template< typename Data, typename DataCompare > + typename IntervalTree::OverlapElements::Locator* IntervalTree::OverlapElements::getLocator () const { return new Locator( tree_, span_ ); } - template< typename Data > - std::string IntervalTree::OverlapElements::_getString () const + template< typename Data, typename DataCompare > + std::string IntervalTree::OverlapElements::_getString () const { std::string s = "<" + _TName("OverlapElements") + " " + getString(tree_) @@ -292,39 +332,45 @@ namespace Hurricane { // Class : "Hurricane::IntervalTree" (implementation). - template< typename Data > - inline void IntervalTree::updateChildsVMax ( typename Super::Node* node ) + template< typename Data, typename DataCompare > + inline void IntervalTree::updateChildsVMax ( typename Super::Node* node ) { + cdebug_log(0,1) << "IntervalTree::updateChildsVMax() " << node->getValue() << endl; DbU::Unit lchildVMax = (node->getLeft ()) ? node->getLeft ()->getValue().getChildsVMax() : node->getValue().getVMax(); DbU::Unit rchildVMax = (node->getRight()) ? node->getRight()->getValue().getChildsVMax() : node->getValue().getVMax(); const_cast< IntervalData& >( node->getValue() ).updateChildsVMax( lchildVMax, rchildVMax ); + cdebug_tabw(0,-1); } - template< typename Data > - void IntervalTree::postRotateLeft ( typename Super::Node* node ) + template< typename Data, typename DataCompare > + void IntervalTree::postRotateLeft ( typename Super::Node* node ) { + cdebug_log(0,1) << "IntervalTree::postRotateLeft() " << node->getValue() << endl; + updateChildsVMax( node ); + if (node->getParent()) updateChildsVMax( node->getParent() ); + cdebug_tabw(0,-1); + } + + + template< typename Data, typename DataCompare > + void IntervalTree::postRotateRight ( typename Super::Node* node ) + { + cdebug_log(0,0) << "IntervalTree::postRotateRight() " << node->getValue() << endl; updateChildsVMax( node ); if (node->getParent()) updateChildsVMax( node->getParent() ); } - template< typename Data > - void IntervalTree::postRotateRight ( typename Super::Node* node ) + template< typename Data, typename DataCompare > + void IntervalTree::postInsert ( typename Super::Node* node ) { - updateChildsVMax( node ); - if (node->getParent()) updateChildsVMax( node->getParent() ); - } - - - template< typename Data > - void IntervalTree::postInsert ( typename Super::Node* node ) - { - cdebug_log(0,1) << "IntervalTree::postInsert() " << node << std::endl; + cdebug_log(0,1) << "IntervalTree::postInsert() " + << ((node) ? ::getString(node->getValue()) : "node=NULL") << std::endl; while ( node ) { - cdebug_log(0,0) << "| " << node << std::endl; + cdebug_log(0,0) << "| " << node->getValue() << std::endl; updateChildsVMax( node ); node = node->getParent(); @@ -334,26 +380,38 @@ namespace Hurricane { } - template< typename Data > - void IntervalTree::postRemove ( typename Super::Node* node ) + template< typename Data, typename DataCompare > + void IntervalTree::postRemove ( typename Super::Node* node ) { + cdebug_log(0,1) << "IntervalTree::postRemove() " + << ((node) ? ::getString(node->getValue()) : "node=NULL") << std::endl; + + if (not node) { + cdebug_tabw(0,-1); + return; + } + typename Super::Node* parent = node->getParent(); if (parent) { - typename Super::Node* child = NULL; + DbU::Unit childsVMax = parent->getValue().getVMax(); + typename Super::Node* child1 = parent->getLeft (); + typename Super::Node* child2 = parent->getRight(); + if (child1 == node) std::swap( child1, child2 ); + if (child1) childsVMax = std::max( childsVMax, child1->getValue().getChildsVMax() ); + if (child2->getLeft ()) childsVMax = std::max( childsVMax, child2->getLeft ()->getValue().getChildsVMax() ); + if (child2->getRight()) childsVMax = std::max( childsVMax, child2->getRight()->getValue().getChildsVMax() ); - if (parent->hasLeftChild(node)) child = parent->getRight(); - else child = parent->getLeft (); - - DbU::Unit childVMax = (child) ? child->getValue().getChildsVMax() : parent->getValue().getVMax(); - const_cast< IntervalData& >( parent->getValue() ).updateChildsVMax( childVMax, childVMax ); + const_cast< IntervalData& >( parent->getValue() ).updateChildsVMax( childsVMax, childsVMax ); postInsert( parent->getParent() ); } + + cdebug_tabw(0,-1); } - template< typename Data > - size_t IntervalTree::getThickness () const + template< typename Data, typename DataCompare > + size_t IntervalTree::getThickness () const { cdebug_log(0,0) << "IntervalTree::getThickness() " << std::endl; @@ -381,34 +439,70 @@ namespace Hurricane { } - template< typename Data > - typename IntervalTree::overlap_iterator IntervalTree::beginOverlaps ( const Interval& overlap ) const + template< typename Data, typename DataCompare > + typename IntervalTree::overlap_iterator + IntervalTree::beginOverlaps ( const Interval& overlap ) const { cdebug_log(0,0) << "IntervalTree::beginOverlaps() " << overlap << std::endl; const typename Super::Node* current = this->getRoot(); - const typename Super::Node* leftMost = NULL; + const typename Super::Node* leftMost = nullptr; while ( current ) { - cdebug_log(0,0) << "| " << ::getString(current) << endl; + cdebug_log(0,0) << "| " << ::getString(current->getValue()) << endl; - if (current->getValue().intersect(overlap)) leftMost = current; + if (current->getValue().intersect(overlap,false)) { + cdebug_log(0,0) << "* Leftmost candidate." << endl; + leftMost = current; + } if ( current->getLeft() - and (overlap.getVMin() < current->getLeft()->getValue().getChildsVMax()) ) - current = current->getLeft(); - else - current = current->getRight(); + and (overlap.getVMin() < current->getLeft()->getValue().getChildsVMax()) ) { + current = current->getLeft(); + leftMost = nullptr; + } else { + if (not leftMost) + current = current->getRight(); + else + current = nullptr; + } } return overlap_iterator( leftMost, overlap ); } - template< typename Data > - typename IntervalTree::OverlapElements IntervalTree::getOverlaps ( const Interval& overlap ) const + template< typename Data, typename DataCompare > + typename IntervalTree::OverlapElements + IntervalTree::getOverlaps ( const Interval& overlap ) const { cdebug_log(0,0) << "IntervalTree::getOverlaps() " << overlap << std::endl; return OverlapElements( *this, overlap ); } + + template< typename Data, typename DataCompare > + void IntervalTree::checkVMax () const + { + checkVMax( this->getRoot() ); + } + + + template< typename Data, typename DataCompare > + void IntervalTree::checkVMax ( typename Super::Node* node ) const + { + if (not node) return; + + DbU::Unit lchildVMax = (node->getLeft ()) ? node->getLeft ()->getValue().getChildsVMax() : node->getValue().getVMax(); + DbU::Unit rchildVMax = (node->getRight()) ? node->getRight()->getValue().getChildsVMax() : node->getValue().getVMax(); + DbU::Unit childsVMax = std::max( lchildVMax, rchildVMax ); + childsVMax = std::max( childsVMax, node->getValue().getVMax() ); + + if (node->getValue().getChildsVMax() != childsVMax) { + cerr << "ChildVMax discrepency on vmax=" << DbU::getValueString(childsVMax) + << " " << ::getString(node->getValue()) << endl; + } + + checkVMax( node->getLeft() ); + checkVMax( node->getRight() ); + } } // HUrricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Occurrence.h b/hurricane/src/hurricane/hurricane/Occurrence.h index b022016a..1becac05 100644 --- a/hurricane/src/hurricane/hurricane/Occurrence.h +++ b/hurricane/src/hurricane/hurricane/Occurrence.h @@ -121,6 +121,10 @@ class JsonOccurrence : public JsonObject { public: virtual void toData(JsonStack&); }; + + typedef std::set OccurrenceSet; + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/RbTree.h b/hurricane/src/hurricane/hurricane/RbTree.h index d441540d..1c1b57da 100644 --- a/hurricane/src/hurricane/hurricane/RbTree.h +++ b/hurricane/src/hurricane/hurricane/RbTree.h @@ -34,9 +34,7 @@ // Third edition, MIT press, 2011, p. 308. -#ifndef HURRICANE_RBTREE_H -#define HURRICANE_RBTREE_H - +#pragma once #include #include #include @@ -90,7 +88,7 @@ namespace Hurricane { inline void copyColor ( Node* ); void updateEdge ( Node* oldChild, Node* newChild ); void clear (); - inline void copy ( const Node* ); + inline void swap ( Node* ); virtual std::string _getString () const; virtual Record* _getRecord () const; private: @@ -284,8 +282,15 @@ namespace Hurricane { template< typename Data, typename Compare > - inline void RbTree::Node::copy ( const Node* other ) - { value_ = other->value_; } + inline void RbTree::Node::swap ( Node* other ) + { + cdebug_log(0,0) << "Node::swap()" << endl; + cdebug_log(0,0) << "| " << value_ << endl; + cdebug_log(0,0) << "| " << other->value_ << endl; + Data tmp = value_; value_ = other->value_; other->value_ = tmp; + cdebug_log(0,0) << "| " << value_ << endl; + cdebug_log(0,0) << "| " << other->value_ << endl; + } template< typename Data, typename Compare > @@ -515,7 +520,7 @@ namespace Hurricane { template< typename Data, typename Compare > void RbTree::rotateLeft ( typename RbTree::Node* node ) { - cdebug_log(0,0) << "RbTree::rotateLeft() " << node << std::endl; + cdebug_log(0,0) << "RbTree::rotateLeft() " << node->getValue() << std::endl; Node* rchild = node->getRight(); @@ -534,7 +539,7 @@ namespace Hurricane { template< typename Data, typename Compare > void RbTree::rotateRight ( typename RbTree::Node* node ) { - cdebug_log(0,0) << "RbTree::rotateRight() " << node << std::endl; + cdebug_log(0,0) << "RbTree::rotateRight() " << node->getValue() << std::endl; Node* lchild = node->getLeft(); @@ -560,12 +565,18 @@ namespace Hurricane { cdebug_log(0,0) << "| " << current->getValue() << std::endl; if (current->getValue() == value) { - cdebug_log(0,-1) << "> Value found: " << current->getValue() < Value found: " << current->getValue() << std::endl; return iterator(current); } - if (compare_(value,current->getValue())) current = current->getLeft (); - else current = current->getRight(); + if (compare_(value,current->getValue())) { + current = current->getLeft (); + cdebug_log(0,0) << "| Go left " << ((current) ? ::getString(current->getValue()) : "NULL") << std::endl; + } + else { + current = current->getRight(); + cdebug_log(0,0) << "| Go right " << ((current) ? ::getString(current->getValue()) : "NULL") << std::endl; + } } cdebug_log(0,-1) << "Value not found." << std::endl; @@ -630,21 +641,22 @@ namespace Hurricane { Node* rmNode = const_cast( find( value ).getNode() ); if (not rmNode) { - cdebug_log(0,1) << "No node of value=" << value << std::endl; + cdebug_log(0,-1) << "No node of value=" << value << std::endl; return; } + Node* rmLeaf = nullptr; if (rmNode->getLeft() and rmNode->getRight()) { - Node* rmLeaf = rmNode->getLeft(); - Node* rmMax = rmLeaf->getMax(); + rmLeaf = rmNode->getLeft(); + Node* rmMax = rmLeaf->getMax(); if (rmMax) rmLeaf = rmMax; - rmNode->copy( rmLeaf ); - rmNode = rmLeaf; + rmNode->swap( rmLeaf ); + std::swap( rmNode, rmLeaf ); } - - postRemove ( rmNode ); + removeRepair( rmNode, 0 ); + postRemove ( rmNode ); Node* parent = rmNode->getParent(); Node* child = (rmNode->getLeft()) ? rmNode->getLeft() : rmNode->getRight(); @@ -660,8 +672,9 @@ namespace Hurricane { } } - cdebug_log(0,0) << "delete " << rmNode << std::endl; + cdebug_log(0,0) << "delete " << rmNode->getValue() << std::endl; delete rmNode; + --count_; cdebug_tabw(0,-1); @@ -671,8 +684,13 @@ namespace Hurricane { template< typename Data, typename Compare > void RbTree::removeRepair ( typename RbTree::Node* rmNode, size_t depth ) { - cdebug_log(0,1) << "RbTree::removeRepair() rmNode:" << rmNode + cdebug_log(0,1) << "RbTree::removeRepair() rmNode:" << rmNode->getValue() << " depth:" << depth << std::endl; + + if (not rmNode) { + cdebug_tabw(0,-1); + return ; + } if (rmNode->isBlack()) { Node* parent = rmNode->getParent(); @@ -979,6 +997,7 @@ namespace Hurricane { void RbTreeToDot::write ( std::ostream& o ) const { o << "digraph RbTree {\n"; + o << " ratio=\"1.0\";\n"; toDot( o, tree_->getRoot() ); o << "}"; } @@ -989,8 +1008,9 @@ namespace Hurricane { { if (not node) return; + string svalue = ::getString( node->getValue() ); o << " id_" << getId(node) << " " - << "[label=\"id:" << getId(node) << "\\n" << ::getString(node->getValue()) + << "[label=\"id:" << getId(node) << "\\n" << split( svalue ) << "\"" << ",color=" << (node->isRed() ? "red" : "black") << ",fontcolor=" << (node->isRed() ? "red" : "black") @@ -1031,6 +1051,3 @@ namespace Hurricane { } // Hurricane namespace. - - -#endif // HURRICANE_RBTREE_H diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp index 02edb928..573dea8e 100644 --- a/hurricane/src/viewer/CellWidget.cpp +++ b/hurricane/src/viewer/CellWidget.cpp @@ -2712,6 +2712,31 @@ namespace Hurricane { } + void CellWidget::selectSet ( const OccurrenceSet& occurrences ) + { + if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) { + openRefreshSession(); + unselectAll(); + closeRefreshSession(); + } + + bool selected = true; + // SelectorCriterion* criterion = _state->getSelection().add ( selectArea ); + // if ( criterion and (not criterion->isEnabled()) ) { + // criterion->enable(); + + for ( const Occurrence& occurrence : occurrences ) { + if (occurrence.getOwnerCell() == getCell()) { + select( occurrence ); + } + } + // } else + // selected = false; + + if ( (--_delaySelectionChanged == 0) and selected ) emit selectionChanged( _selectors ); + } + + void CellWidget::select ( Occurrence occurrence ) { if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) { @@ -2823,6 +2848,18 @@ namespace Hurricane { } + void CellWidget::unselectSet ( const OccurrenceSet& occurrences ) + { + ++_delaySelectionChanged; + for ( const Occurrence& occurrence : occurrences ) { + if (occurrence.getOwnerCell() == getCell()) { + unselect( occurrence ); + } + } + if ( --_delaySelectionChanged == 0 ) emit selectionChanged( _selectors ); + } + + void CellWidget::unselectAll () { ++_delaySelectionChanged; diff --git a/hurricane/src/viewer/hurricane/viewer/CellWidget.h b/hurricane/src/viewer/hurricane/viewer/CellWidget.h index 5b277e3f..51abdff6 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/CellWidget.h @@ -265,12 +265,14 @@ namespace Hurricane { inline DrawingPlanes& getDrawingPlanes (); // void select ( const Net* ); void select ( Occurrence ); + void selectSet ( const OccurrenceSet& ); void selectSet ( const ComponentSet& ); bool isSelected ( Occurrence ); void selectOccurrencesUnder ( Box selectArea ); // void unselect ( const Net* ); void unselect ( Occurrence ); void unselectSet ( const ComponentSet& ); + void unselectSet ( const OccurrenceSet& ); void unselectAll (); void toggleSelection ( Occurrence ); void setShowSelection ( bool state ); diff --git a/tramontana/src/CMakeLists.txt b/tramontana/src/CMakeLists.txt index b916b224..56692952 100644 --- a/tramontana/src/CMakeLists.txt +++ b/tramontana/src/CMakeLists.txt @@ -10,8 +10,10 @@ ${Python_INCLUDE_DIRS} ) set( includes tramontana/Tile.h + tramontana/QueryTiles.h tramontana/SweepLine.h tramontana/Equipotential.h + tramontana/EquipotentialRelation.h tramontana/TramontanaEngine.h tramontana/GraphicTramontanaEngine.h ) @@ -24,8 +26,10 @@ tramontana/TabEquipotentials.h ) set( cpps Tile.cpp + QueryTiles.cpp SweepLine.cpp Equipotential.cpp + EquipotentialRelation.cpp TramontanaEngine.cpp GraphicTramontanaEngine.cpp EquipotentialsModel.cpp diff --git a/tramontana/src/Equipotential.cpp b/tramontana/src/Equipotential.cpp index 6a7f6574..c5092f00 100644 --- a/tramontana/src/Equipotential.cpp +++ b/tramontana/src/Equipotential.cpp @@ -37,12 +37,14 @@ #include "hurricane/RoutingPad.h" #include "crlcore/Utilities.h" #include "tramontana/Equipotential.h" +#include "tramontana/EquipotentialRelation.h" #include "tramontana/TramontanaEngine.h" namespace { using Hurricane::Net; + using Hurricane::Occurrence; class NetCompareByName { @@ -63,6 +65,24 @@ namespace { } + 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. @@ -158,19 +178,11 @@ namespace Tramontana { Box Equipotential::getBoundingBox () const { return _boundingBox; } - - void Equipotential::add ( Component* component ) + + void Equipotential::add ( Occurrence component, const Box& boundingBox ) { _components.insert( component ); - } - - - void Equipotential::add ( Occurrence child ) - { - if (child.getPath().isEmpty()) - add( dynamic_cast( child.getEntity() )); - else - _childs.push_back( child ); + _boundingBox.merge( boundingBox ); } @@ -184,20 +196,26 @@ namespace Tramontana { return; } - for ( Component* component : other->getComponents() ) { - add( component ); - } - for ( Occurrence child : other->getChilds() ) { - add( child ); - } + for ( const Occurrence& component : other->getComponents() ) add( component ); + for ( const Occurrence& child : other->getChilds () ) add( child ); + _boundingBox.merge( other->_boundingBox ); other->clear(); } void Equipotential::consolidate () { - set nets; - for ( Component* component : getComponents() ) { + EquipotentialRelation* relation = EquipotentialRelation::create( this ); + set nets; + set deepNets; + for ( const Occurrence& occurrence : getComponents() ) { + Component* component = dynamic_cast( occurrence.getEntity() ); + if (not component) continue; + if (not occurrence.getPath().isEmpty()) { + deepNets.insert( Occurrence( component->getNet(), occurrence.getPath() )); + continue; + } + component->put( relation ); Net* net = component->getNet(); if (net->isFused()) _hasFused = true; else { @@ -209,8 +227,17 @@ namespace Tramontana { } nets.insert( component->getNet() ); } - _name = getString( (*nets.begin())->getName() ); + if (not nets.empty()) { + _name = getString( (*nets.begin())->getName() ); + } else { + if (not deepNets.empty()) { + _name = (*deepNets.begin()).getCompactString(); + } + } _netCount = nets.size(); + + // if (_name == "abc_11873_auto_rtlil_cc_2560_muxgate_11612") + // show(); } @@ -221,6 +248,20 @@ namespace Tramontana { } + void Equipotential::show () const + { + cerr << this << endl; + cerr << "+ Components:" << endl; + for ( const Occurrence& component : _components ) { + cerr << "| " << component << endl; + } + cerr << "+ Occurrences:" << endl; + for ( Occurrence occ : _childs ) { + cerr << "| " << occ << endl; + } + } + + string Equipotential::getFlagsAsString () const { string sflags; diff --git a/tramontana/src/EquipotentialRelation.cpp b/tramontana/src/EquipotentialRelation.cpp new file mode 100644 index 00000000..bcd9af95 --- /dev/null +++ b/tramontana/src/EquipotentialRelation.cpp @@ -0,0 +1,81 @@ +// -*- 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 : "./EquipotentialRelation.cpp" | +// +-----------------------------------------------------------------+ + + +#include "tramontana/EquipotentialRelation.h" + + +namespace Tramontana { + + using std::string; + using Hurricane::Property; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::EquipotentialRelation". + + const Name EquipotentialRelationName = "EquipotentialRelation"; + + + EquipotentialRelation::EquipotentialRelation ( Equipotential* owner ) + : Super(owner) + { } + + + EquipotentialRelation* EquipotentialRelation::create ( Equipotential* owner ) + { + EquipotentialRelation* relation = new EquipotentialRelation ( owner ); + relation->_postCreate(); + return relation; + } + + + void EquipotentialRelation::_preDestroy () + { Super::_preDestroy(); } + + + Name EquipotentialRelation::getName () const + { return EquipotentialRelationName; } + + + string EquipotentialRelation::_getTypeName () const + { return "EquipotentialRelation"; } + + + Record* EquipotentialRelation::_getRecord () const + { + Record* record = Super::_getRecord(); + return record; + } + + + EquipotentialRelation* EquipotentialRelation::get ( const Component* component ) + { + if (not component) return nullptr; + + Property* property = component->getProperty( EquipotentialRelationName ); + if (not property) return nullptr; + + EquipotentialRelation* relation = dynamic_cast( property ); + if (not relation) return nullptr; + return relation; + } + + + +} // Tramontana namespace. + diff --git a/tramontana/src/EquipotentialsWidget.cpp b/tramontana/src/EquipotentialsWidget.cpp index f6ec7a57..f4f39bf8 100644 --- a/tramontana/src/EquipotentialsWidget.cpp +++ b/tramontana/src/EquipotentialsWidget.cpp @@ -104,7 +104,7 @@ namespace Tramontana { , this , SLOT (textFilterChanged()) ); connect( _view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)) , this , SLOT (updateSelecteds (const QItemSelection&,const QItemSelection&)) ); - //connect( fitAction, SIGNAL(triggered()), this, SLOT(fitToEqui()) ); + connect( fitAction, SIGNAL(triggered()), this, SLOT(fitToEqui()) ); resize( 300, 300 ); } @@ -180,11 +180,11 @@ namespace Tramontana { } - // void EquipotentialsWidget::fitToNet () - // { - // const Equipotential* equi = _baseModel->getEqui( _sortModel->mapToSource(_view->currentIndex()).row() ); - // if (equi) emit netFitted ( equi ); - // } + void EquipotentialsWidget::fitToEqui () + { + const Equipotential* equi = _baseModel->getEqui( _sortModel->mapToSource(_view->currentIndex()).row() ); + if (equi) emit reframe ( equi->getBoundingBox() ); + } void EquipotentialsWidget::setCellWidget ( CellWidget* cw ) @@ -196,7 +196,7 @@ namespace Tramontana { _cellWidget = cw; if (_cellWidget) { setCell( _cellWidget->getCell() ); - //connect( this, SIGNAL(netFitted(const Equi*)), _cellWidget, SLOT(fitToEqui (const Equi*)) ); + connect( this, SIGNAL( reframe(const Box&) ), _cellWidget, SLOT( reframe(const Box&) )); } else setCell( nullptr ); } diff --git a/tramontana/src/QueryTiles.cpp b/tramontana/src/QueryTiles.cpp new file mode 100644 index 00000000..eb3f4833 --- /dev/null +++ b/tramontana/src/QueryTiles.cpp @@ -0,0 +1,91 @@ +// -*- 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 : "./QueryTiles.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "tramontana/QueryTiles.h" +#include "tramontana/SweepLine.h" + + +namespace Tramontana { + + using std::cerr; + using std::endl; + using std::vector; + + + QueryTiles::QueryTiles ( SweepLine* sweepLine ) + : Query () + , _sweepLine (sweepLine) + , _goMatchCount (0) + , _processedLayers(0) + { + setCell ( sweepLine->getCell() ); + setArea ( sweepLine->getCell()->getBoundingBox() ); + setFilter( Query::DoComponents|Query::DoTerminalCells ); + } + + + void QueryTiles::setBasicLayer ( const BasicLayer* basicLayer ) + { + _processedLayers |= basicLayer->getMask(); + Query::setBasicLayer ( basicLayer ); + } + + + bool QueryTiles::isProcessed ( Component* component ) const + { + Layer::Mask fullyProcesseds = _processedLayers & ~getBasicLayer()->getMask(); + return component->getLayer()->getMask().intersect( fullyProcesseds ); + } + + + void QueryTiles::masterCellCallback () + { } + + + void QueryTiles::rubberCallback ( Rubber* ) + { } + + + void QueryTiles::extensionGoCallback ( Go* ) + { } + + + bool QueryTiles::hasGoCallback () const + { return true; } + + + void QueryTiles::goCallback ( Go* go ) + { + vector tiles; + Component* component = dynamic_cast( go ); + if (not component) return; + if (isProcessed(component)) return; + Occurrence occurrence = Occurrence( go, getPath() ); + for ( const BasicLayer* layer : _sweepLine->getExtracteds() ) { + if (not component->getLayer()->getMask().intersect(layer->getMask())) continue; + tiles.push_back( Tile::create( occurrence, layer )); + _sweepLine->add( tiles.back() ); + if (tiles.size() > 1) + tiles.back()->setParent( tiles[0] ); + } + _goMatchCount++; + } + + +} // Tramontana namespace. diff --git a/tramontana/src/SweepLine.cpp b/tramontana/src/SweepLine.cpp index c40715a1..cced774e 100644 --- a/tramontana/src/SweepLine.cpp +++ b/tramontana/src/SweepLine.cpp @@ -38,6 +38,7 @@ #include "hurricane/RoutingPad.h" #include "crlcore/Utilities.h" #include "tramontana/SweepLine.h" +#include "tramontana/QueryTiles.h" namespace Tramontana { @@ -84,9 +85,24 @@ namespace Tramontana { SweepLine::SweepLine ( TramontanaEngine* tramontana ) : _tramontana (tramontana) + , _extracteds () , _tiles () , _intervalTrees() - { } + { + 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) + _extracteds.push_back( bl ); + } + + // _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal5" )); + // _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal4" )); + // _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal3" )); + // _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal2" )); + // _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal1" )); + // _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "poly" )); + } SweepLine::~SweepLine () @@ -95,13 +111,26 @@ namespace Tramontana { void SweepLine::run () { - //cerr << "SweepLine::run()" << endl; - //DebugSession::open( 0, 2 ); + //DebugSession::open( 160, 169 ); + cdebug_log(160,1) << "SweepLine::run()" << endl; loadTiles(); + //bool debugOn = false; + bool written = false; for ( Element& element : _tiles ) { Tile* tile = element.getTile(); TileIntv tileIntv ( tile, tile->getYMin(), tile->getYMax() ); - //cerr << right << setw(10) << DbU::getValueString(element.getX()) << " > " << tile << endl; + // if (getString(tile->getNet()->getName()) == "a(13)") { + // cerr << tile << endl; + // } + // if (not debugOn and (element.getX() == DbU::fromLambda(1724.0))) { + // debugOn = true; + // DebugSession::open( 0, 169 ); + // } + // if (debugOn and (element.getX() > DbU::fromLambda(1726.0))) { + // debugOn = false; + // DebugSession::close(); + // } + cdebug_log(160,1) << "X@ + " << DbU::getValueString(element.getX()) << " " << tile << endl; auto intvTree = _intervalTrees.find( element.getMask() ); if (intvTree == _intervalTrees.end()) { cerr << Error( "SweepLine::run(): Missing interval tree for layer(mask) %s." @@ -109,19 +138,77 @@ namespace Tramontana { , getString(element.getMask()).c_str() , getString(element.getTile()).c_str() ) << endl; + cdebug_tabw(160,-1); continue; } if (element.isLeftEdge()) { + // if (tile->getId() == 60117) { + // DebugSession::open( 0, 169 ); + // if (not written) intvTree->second.write( "tree-before.gv" ); + // cdebug_log(160,0) << " Interval tree *before* insertion." << endl; + // for ( auto elt : intvTree->second.getElements() ) { + // cdebug_log(160,0) << " | in tree:" << elt << endl; + // if (elt.getData()->getBoundingBox().getXMax() < tile->getLeftEdge()) + // cdebug_log(160,0) << " * Should have been removed !" << endl; + // } + // } for ( const TileIntv& overlap : intvTree->second.getOverlaps( Interval(tile->getYMin(), tile->getYMax() ))) { - //cerr << " | intersect " << overlap.getData() << endl; + cdebug_log(160,0) << " | intersect " << overlap.getData() << endl; tile->merge( overlap.getData() ); } - //cerr << " | insert tile" << endl; + cdebug_log(160,0) << " | insert tile" << endl; + // if (tile->getId() == 60117) { + // cerr << " | insert in " << element.getMask() << endl; + // cerr << " | " << tile << endl; + // } + // if (tile->getId() == 46373) { + // cerr << " | insert " << tile << endl; + // } intvTree->second.insert( tileIntv ); + // if (tile->getId() == 60117) { + // if (not written) intvTree->second.write( "tree-after.gv" ); + // written = true; + // DebugSession::close(); + // } } else { - //cerr << " | remove tile" << endl; + // if (tile->getId() == 289) { + // DebugSession::open( 0, 169 ); + // } + // cdebug_log(160,0) << " | remove tile from " << element.getMask() << endl; + // cdebug_log(160,0) << " | " << tile << endl; + // if ((tile->getId() == 289) and not written) { + // cerr << "(before) written is " << written << endl; + // DebugSession::open( 0, 169 ); + // intvTree->second.write( "tree-before.gv" ); + // //DebugSession::close(); + // for ( auto elt : intvTree->second.getElements() ) { + // cerr << " | in tree:" << elt << endl; + // } + // } + cdebug_log(160,0) << " | remove tile" << endl; intvTree->second.remove( tileIntv ); + //DebugSession::open( 0, 169 ); + intvTree->second.checkVMax(); + //DebugSession::close(); + // if ((tile->getId() == 289) and not written) { + // //DebugSession::open( 0, 169 ); + // written = true; + // cerr << "(after) written is " << written << endl; + // intvTree->second.write( "tree-after.gv" ); + // DebugSession::close(); + // } + // if (intvTree->second.find( tileIntv ) != intvTree->second.end()) { + // cerr << "NOT Removed " << tileIntv << endl; + // } + // if (tile->getId() == 289) { + // cerr << " | removed " << tile << endl; + // intvTree->second.write( "tree.gv" ); + // for ( auto elt : intvTree->second.getElements() ) { + // cerr << " | in tree:" << elt << endl; + // } + // DebugSession::close(); + // } // if (tile->getId() == 46055) { // intvTree->second.write( "we_at_remove.gv" ); // for ( auto tile : intvTree->second.getElements() ) { @@ -129,7 +216,11 @@ namespace Tramontana { // } // } } + intvTree->second.checkVMax(); + cdebug_tabw(160,-1); } + //if (debugOn) DebugSession::close(); + cdebug_tabw(160,-1); //DebugSession::close(); mergeEquipotentials(); } @@ -138,37 +229,35 @@ namespace Tramontana { void SweepLine::loadTiles () { //cerr << "SweepLine::loadTiles()" << endl; - vector extracteds; - for ( const BasicLayer* bl : DataBase::getDB()->getTechnology()->getBasicLayers() ) { - if (bl->getMaterial() == BasicLayer::Material::metal) - extracteds.push_back( bl ); - } - - // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal5" )); - // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal4" )); - // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal3" )); - // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal2" )); - // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal1" )); - // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "poly" )); - for ( const BasicLayer* layer : extracteds ) { + for ( const BasicLayer* layer : _extracteds ) { _intervalTrees.insert( make_pair( layer->getMask(), TileIntvTree() )); } - for ( Occurrence occurrence : getCell()->getOccurrencesUnder( getCell()->getBoundingBox() ) ) { - vector tiles; - Component* component = dynamic_cast( occurrence.getEntity() ); - if (not component) continue; - for ( const BasicLayer* layer : extracteds ) { - if (not component->getLayer()->getMask().intersect(layer->getMask())) continue; - tiles.push_back( Tile::create( occurrence, layer )); - _tiles.push_back( Element( tiles.back(), Tile::LeftEdge ) ); - _tiles.push_back( Element( tiles.back(), Tile::RightEdge ) ); - if (tiles.size() > 1) - tiles.back()->setParent( tiles[0] ); - } - tiles.clear(); + QueryTiles query ( this ); + for ( const BasicLayer* layer : _extracteds ) { + query.setBasicLayer( layer ); + query.doQuery(); } + cmess2 << " - Loaded " << query.getGoMatchCount() << " tiles." << endl; + + // for ( Occurrence occurrence : getCell()->getOccurrencesUnder( getCell()->getBoundingBox() ) ) { + // vector tiles; + // Component* component = dynamic_cast( occurrence.getEntity() ); + // if (occurrence.getPath().getInstances().getSize() > 0) { + // cerr << occurrence << endl; + // } + // if (not component) continue; + // for ( const BasicLayer* layer : extracteds ) { + // if (not component->getLayer()->getMask().intersect(layer->getMask())) continue; + // tiles.push_back( Tile::create( occurrence, layer )); + // _tiles.push_back( Element( tiles.back(), Tile::LeftEdge ) ); + // _tiles.push_back( Element( tiles.back(), Tile::RightEdge ) ); + // if (tiles.size() > 1) + // tiles.back()->setParent( tiles[0] ); + // } + // tiles.clear(); + // } sort( _tiles.begin(), _tiles.end() ); } diff --git a/tramontana/src/TabEquipotentials.cpp b/tramontana/src/TabEquipotentials.cpp index 78829b4f..0c4ecac2 100644 --- a/tramontana/src/TabEquipotentials.cpp +++ b/tramontana/src/TabEquipotentials.cpp @@ -96,14 +96,14 @@ namespace Tramontana { getCellWidget()->closeRefreshSession (); } getCellWidget()->setShowSelection( true ); - connect( _browser, SIGNAL(equipotentialSelect (const ComponentSet&)), getCellWidget(), SLOT(selectSet (const ComponentSet&)) ); - connect( _browser, SIGNAL(equipotentialUnselect(const ComponentSet&)), getCellWidget(), SLOT(unselectSet(const ComponentSet&)) ); + connect( _browser, SIGNAL(equipotentialSelect (const OccurrenceSet&)), getCellWidget(), SLOT(selectSet (const OccurrenceSet&)) ); + connect( _browser, SIGNAL(equipotentialUnselect(const OccurrenceSet&)), getCellWidget(), SLOT(unselectSet(const OccurrenceSet&)) ); _browser->updateSelecteds(); } else { getCellWidget()->setShowSelection( false ); getCellWidget()->setCumulativeSelection( _cwCumulativeSelection ); - _browser->disconnect( getCellWidget(), SLOT(selectSet (const ComponentSet&)) ); - _browser->disconnect( getCellWidget(), SLOT(unselectSet(const ComponentSet&)) ); + _browser->disconnect( getCellWidget(), SLOT(selectSet (const OccurrenceSet&)) ); + _browser->disconnect( getCellWidget(), SLOT(unselectSet(const OccurrenceSet&)) ); } } diff --git a/tramontana/src/Tile.cpp b/tramontana/src/Tile.cpp index 550778cb..8c2eefa8 100644 --- a/tramontana/src/Tile.cpp +++ b/tramontana/src/Tile.cpp @@ -133,9 +133,14 @@ namespace Tramontana { { } + 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; Tile* root = this; while ( root->getParent() ) { @@ -145,6 +150,7 @@ namespace Tramontana { } root = root->getParent(); } + cdebug_log(160,0) << "> root " << root->getId() << endl; if (flags & Compress) { Tile* current = this; @@ -166,16 +172,18 @@ namespace Tramontana { if (current->isUpToDate()) break; if (current->getEquipotential()) { if (current->getEquipotential() != rootEqui) { + cdebug_log(160,0) << "| merge " << current->getId() << " => " << root->getId() << endl; rootEqui->merge( current->getEquipotential() ); } } else { - rootEqui->add( current->getOccurrence() ); + rootEqui->add( current->getOccurrence(), _boundingBox ); } current->syncTime(); current = current->getParent(); } } + cdebug_tabw(160,-1); return root; } @@ -208,7 +216,9 @@ namespace Tramontana { } _equipotential = Equipotential::create( _occurrence.getOwnerCell() ); - _equipotential->add( _occurrence ); + _equipotential->add( _occurrence, _boundingBox ); + //cerr << "new " << _equipotential << endl; + //cerr << "| " << _occurrence << endl; return _equipotential; } diff --git a/tramontana/src/TramontanaEngine.cpp b/tramontana/src/TramontanaEngine.cpp index e31252f2..6631b0df 100644 --- a/tramontana/src/TramontanaEngine.cpp +++ b/tramontana/src/TramontanaEngine.cpp @@ -199,10 +199,7 @@ namespace Tramontana { { cerr << "Equipotentials:" << endl; for ( Equipotential* equi : _equipotentials ) { - cerr << equi << endl; - for ( Component* component : equi->getComponents() ) { - cerr << "| " << component << endl; - } + equi->show(); } } diff --git a/tramontana/src/tramontana/Equipotential.h b/tramontana/src/tramontana/Equipotential.h index f8f9bb5b..0c9ceb90 100644 --- a/tramontana/src/tramontana/Equipotential.h +++ b/tramontana/src/tramontana/Equipotential.h @@ -18,12 +18,10 @@ #pragma once #include -#include +#include +#include "hurricane/Net.h" #include "hurricane/Component.h" #include "hurricane/Occurrence.h" -namespace Hurricane { - class Net; -} namespace Tramontana { @@ -38,7 +36,7 @@ namespace Tramontana { using Hurricane::Net; using Hurricane::Cell; using Hurricane::Component; - using Hurricane::ComponentSet; + using Hurricane::OccurrenceSet; using Hurricane::Occurrence; @@ -49,60 +47,60 @@ 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; - inline bool hasComponent ( Component* ) const; - void add ( Component* ); - void add ( Occurrence ); - void merge ( Equipotential* ); - void consolidate (); - void clear (); - inline const ComponentSet& getComponents () const; - inline const std::vector& 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* 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; private: - Cell* _owner; - Box _boundingBox; - ComponentSet _components; - std::vector _childs; - std::string _name; - Net::Type _type; - Net::Direction _direction; - uint32_t _netCount; - bool _isExternal; - bool _isGlobal; - bool _isAutomatic; - bool _hasFused; + Cell* _owner; + Box _boundingBox; + OccurrenceSet _components; + OccurrenceSet _childs; + std::string _name; + Net::Type _type; + Net::Direction _direction; + uint32_t _netCount; + bool _isExternal; + bool _isGlobal; + bool _isAutomatic; + bool _hasFused; }; - inline bool Equipotential::isEmpty () const { return _components.empty() and _childs.empty(); } - inline const ComponentSet& Equipotential::getComponents () const { return _components; } - 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::getChilds () const { return _childs; } + 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 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( component ) != _components.end(); } + { return _components.find( Occurrence(component) ) != _components.end(); } } // Tramontana namespace. diff --git a/tramontana/src/tramontana/EquipotentialRelation.h b/tramontana/src/tramontana/EquipotentialRelation.h new file mode 100644 index 00000000..0102c267 --- /dev/null +++ b/tramontana/src/tramontana/EquipotentialRelation.h @@ -0,0 +1,54 @@ +// -*- 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/EquipotentialRelation.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include "hurricane/Relation.h" +#include "tramontana/TramontanaEngine.h" + + +namespace Tramontana { + + using Hurricane::Name; + using Hurricane::Record; + using Hurricane::Relation; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::EquipotentialRelation". + + class EquipotentialRelation : public Relation { + public: + typedef Relation Super; + public: + static EquipotentialRelation* get ( const Component* ); + static EquipotentialRelation* create ( Equipotential* ); + public: + virtual Name getName () const; + virtual std::string _getTypeName () const; + virtual Record* _getRecord () const; + private: + EquipotentialRelation ( Equipotential* ); + protected: + virtual void _preDestroy (); + }; + + +} // Tramontana namespace. + + +INSPECTOR_P_SUPPORT(Tramontana::EquipotentialRelation); diff --git a/tramontana/src/tramontana/EquipotentialsWidget.h b/tramontana/src/tramontana/EquipotentialsWidget.h index 4ebdcb04..ec48d62f 100644 --- a/tramontana/src/tramontana/EquipotentialsWidget.h +++ b/tramontana/src/tramontana/EquipotentialsWidget.h @@ -44,6 +44,7 @@ namespace Tramontana { using std::set; using Hurricane::Cell; using Hurricane::CellWidget; + using Hurricane::OccurrenceSet; // ------------------------------------------------------------------- @@ -136,13 +137,13 @@ namespace Tramontana { void goTo ( int ); void updateSelecteds (); signals: - void equipotentialSelect ( const ComponentSet& ); - void equipotentialUnselect ( const ComponentSet& ); - void netFitted ( const Equipotential* ); + void equipotentialSelect ( const OccurrenceSet& ); + void equipotentialUnselect ( const OccurrenceSet& ); + void reframe ( const Box& ); private slots: void textFilterChanged (); void updateSelecteds ( const QItemSelection& , const QItemSelection& ); - // void fitToEqui (); + void fitToEqui (); private: CellWidget* _cellWidget; diff --git a/tramontana/src/tramontana/QueryTiles.h b/tramontana/src/tramontana/QueryTiles.h new file mode 100644 index 00000000..b1742013 --- /dev/null +++ b/tramontana/src/tramontana/QueryTiles.h @@ -0,0 +1,60 @@ +// -*- 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/QueryTiles.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include "hurricane/Query.h" + + +namespace Tramontana { + + using Hurricane::Box; + using Hurricane::DbU; + using Hurricane::Layer; + using Hurricane::BasicLayer; + using Hurricane::Go; + using Hurricane::Component; + using Hurricane::Rubber; + using Hurricane::Query; + class SweepLine; + + +// ------------------------------------------------------------------- +// Class : "Tramontana::QueryTiles". + + class QueryTiles : public Query { + public: + QueryTiles ( SweepLine* ); + bool isProcessed ( Component* ) const; + virtual void setBasicLayer ( const BasicLayer* ); + virtual bool hasGoCallback () const; + virtual void goCallback ( Go* ); + virtual void rubberCallback ( Rubber* ); + virtual void extensionGoCallback ( Go* ); + virtual void masterCellCallback (); + inline uint32_t getGoMatchCount () const; + private: + SweepLine* _sweepLine; + uint32_t _goMatchCount; + Layer::Mask _processedLayers; + }; + + + inline uint32_t QueryTiles::getGoMatchCount () const { return _goMatchCount; } + + +} // Tramontana namespace. diff --git a/tramontana/src/tramontana/SweepLine.h b/tramontana/src/tramontana/SweepLine.h index 0fb6d0eb..b7f8be26 100644 --- a/tramontana/src/tramontana/SweepLine.h +++ b/tramontana/src/tramontana/SweepLine.h @@ -49,6 +49,7 @@ namespace Tramontana { public: inline Element ( Tile*, uint32_t flags ); inline bool operator< ( const Element& ) const; + inline bool operator== ( const Element& ) const; inline bool isLeftEdge () const; inline Tile* getTile () const; inline DbU::Unit getX () const; @@ -63,8 +64,11 @@ namespace Tramontana { SweepLine ( TramontanaEngine* ); ~SweepLine (); inline Cell* getCell (); + inline const std::vector& + getExtracteds () const; void run (); void loadTiles (); + inline void add ( Tile* ); void mergeEquipotentials (); Record* _getRecord () const; std::string _getString () const; @@ -73,9 +77,10 @@ namespace Tramontana { SweepLine ( const SweepLine& ) = delete; SweepLine& operator= ( const SweepLine& ) = delete; private: - TramontanaEngine* _tramontana; - std::vector _tiles; - IntervalTrees _intervalTrees; + TramontanaEngine* _tramontana; + std::vector _extracteds; + std::vector _tiles; + IntervalTrees _intervalTrees; }; @@ -91,14 +96,26 @@ namespace Tramontana { inline bool SweepLine::Element::operator< ( const Element& rhs ) const { if (getX() != rhs.getX()) return (getX() < rhs.getX()); + if (isLeftEdge() xor rhs.isLeftEdge()) return isLeftEdge(); if (getY() != rhs.getY()) return (getY() < rhs.getY()); if (getMask() != rhs.getMask()) return (getMask() < rhs.getMask()); - return getId() < rhs.getId(); + return TileCompare() ( getTile(), rhs.getTile() ); } + + inline bool SweepLine::Element::operator== ( const Element& rhs ) const + { return getTile() == rhs.getTile(); } + // SweepLine. inline Cell* SweepLine::getCell () { return _tramontana->getCell(); } + inline const std::vector& SweepLine::getExtracteds () const { return _extracteds; } + + inline void SweepLine::add ( Tile* tile ) + { + _tiles.push_back( Element( tile, Tile::LeftEdge ) ); + _tiles.push_back( Element( tile, Tile::RightEdge ) ); + } diff --git a/tramontana/src/tramontana/Tile.h b/tramontana/src/tramontana/Tile.h index a8bf7db9..f73f1242 100644 --- a/tramontana/src/tramontana/Tile.h +++ b/tramontana/src/tramontana/Tile.h @@ -68,8 +68,9 @@ namespace Tramontana { Tile* getRoot ( uint32_t flags=Compress ); inline Component* getComponent () const; inline Occurrence getOccurrence () const; + Net* getNet () const; inline Layer::Mask getMask () const; - inline const BasicLayer* getLayer () const; + inline const BasicLayer* getLayer () const; inline const Box& getBoundingBox () const; inline Equipotential* getEquipotential () const; inline DbU::Unit getLeftEdge () const; @@ -128,12 +129,22 @@ namespace Tramontana { inline void Tile::setEquipotential ( Equipotential* equi ) { _equipotential=equi; } + class TileCompare { + public: + inline bool operator() ( const Tile* lhs, const Tile* rhs ) const + { + cdebug_log(0,0) << "TileCompare::operator()" << std::endl; + return lhs->getOccurrence() < rhs->getOccurrence(); + } + }; + + // ------------------------------------------------------------------- // Class : "Tramontana::TileIntvTree". - typedef IntervalData TileIntv; - typedef IntervalTree TileIntvTree; + typedef IntervalData TileIntv; + typedef IntervalTree TileIntvTree; } // Tramontana namespace.