Transhierarchical/flat extraction work, no netlist rebuild yet.

* Bug: In Interval::intersect(), bad condition check in strict mode.
* Change: In Occurrence::operator<(), change the sorting criterions
    so that the ones with no paths are "lower", then the one with
    no entities, then compare entities Id then Path hashes.
* Change: In Occurrence::getCompactString(), to be more readable,
    suppress leading and ending "<>".
* Change: In IntervalTree, now use an IntervalDataCompare to control
    the ordering of the nodes inside the tree. This may be needed
    when IntervalData is build upon a pointer, we don't want to
    sort on pointer values (non deterministic) .
* Bug: In IntervalTree::postRemove(), there was an incorrect computation
    of the updated childsVMax.
* Bug: In IntervalTree::beginOverlaps(), miscalculated leftmost
    interval overlapping.
* Bug: In RbTree::remove(), when exchanging the removed node for a
    leaf, fully swap the nodes contents, was incompletly copied before.
* New: In CellWidget, add new slots selectSet(OccurrenceSet&) and
    unselectSet(OccurrenceSet&), to be able to select/unselected sets
    of Occurrence (for use by TabEquipotentials).
* Change: In EtesianEngine, no more need to remove leading/ending "<>".
* New: In Tramontana, use a Query to find all the Occurrence under
    an area. Previously we were using Cell::getOccurrencesUnder()
    which *do not* return the components in instances, so we would
    have been unable to find trans-hierarchical shorts circuits.
* New: In tramontana, now use a Relation to tag all the components
    belonging to an Equipotential.
* Change: In Equipotential, store everything under the form of
    Occurrence, instead of Components. Due to the way the Occurrences
    are sorted, the one holding Components should be firts.
This commit is contained in:
Jean-Paul Chaput 2023-04-02 23:02:46 +02:00
parent 6361ad4ca0
commit 518a376c01
25 changed files with 891 additions and 258 deletions

View File

@ -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<Instance*>(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() ) {

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -146,6 +146,9 @@ namespace Hurricane {
}
string& split ( std::string& );
} // End of Hurricane namespace.

View File

@ -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<Data>::IntervalData ()
: Interval(1,-1)
@ -91,9 +92,19 @@ namespace Hurricane {
template< typename Data >
inline DbU::Unit IntervalData<Data>::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<Data>::operator== ( const IntervalData<Data>& other ) const
{ return Interval::operator==(*this) and (data_ == other.data_); }
template< typename Data >
std::string IntervalData<Data>::_getString () const
{
@ -116,13 +127,34 @@ namespace Hurricane {
}
// -------------------------------------------------------------------
// Class : "Hurricane::IntervalDataCompare".
template< typename Data, typename DataCompare=std::less<Data> >
class IntervalDataCompare {
public:
inline bool operator() ( const IntervalData<Data>& lhs, const IntervalData<Data>& 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<Data>, Interval::CompareByMinMax > {
template< typename Data, typename DataCompare=std::less<Data> >
class IntervalTree : public RbTree< IntervalData<Data>, IntervalDataCompare<Data,DataCompare> > {
public:
typedef RbTree< IntervalData<Data>, Interval::CompareByMinMax > Super;
typedef RbTree< IntervalData<Data>, IntervalDataCompare<Data,DataCompare> > 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<Data>::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap )
template< typename Data, typename DataCompare >
IntervalTree<Data,DataCompare>::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap )
: Super::iterator(node)
, overlap_(overlap)
{ }
template< typename Data >
typename IntervalTree<Data>::overlap_iterator& IntervalTree<Data>::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<Data,DataCompare>::overlap_iterator&
IntervalTree<Data,DataCompare>::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<Data>::OverlapElements::Locator::Locator ( const Locator &locator )
template< typename Data, typename DataCompare >
inline IntervalTree<Data,DataCompare>::OverlapElements::Locator::Locator ( const Locator &locator )
: Hurricane::Locator< IntervalData<Data> >()
, iterator_(locator.iterator_)
{ }
template< typename Data >
IntervalTree<Data>::OverlapElements::Locator::Locator ( const IntervalTree<Data>& tree, const Interval& span )
template< typename Data, typename DataCompare >
IntervalTree<Data,DataCompare>::OverlapElements::Locator::Locator ( const IntervalTree<Data,DataCompare>& tree, const Interval& span )
: Hurricane::Locator< IntervalData<Data> >()
, iterator_(tree.beginOverlaps(span))
{ }
template< typename Data >
typename IntervalTree<Data>::OverlapElements::Locator* IntervalTree<Data>::OverlapElements::Locator::getClone () const
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::OverlapElements::Locator*
IntervalTree<Data,DataCompare>::OverlapElements::Locator::getClone () const
{ return new Locator(*this); }
template< typename Data >
IntervalData<Data> IntervalTree<Data>::OverlapElements::Locator::getElement () const
template< typename Data, typename DataCompare >
IntervalData<Data> IntervalTree<Data,DataCompare>::OverlapElements::Locator::getElement () const
{ return (*iterator_); }
template< typename Data >
bool IntervalTree<Data>::OverlapElements::Locator::isValid () const
template< typename Data, typename DataCompare >
bool IntervalTree<Data,DataCompare>::OverlapElements::Locator::isValid () const
{ return iterator_.isValid(); }
template< typename Data >
void IntervalTree<Data>::OverlapElements::Locator::progress ()
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::OverlapElements::Locator::progress ()
{
if (isValid()) ++iterator_;
}
template< typename Data >
std::string IntervalTree<Data>::OverlapElements::Locator::_getString () const
template< typename Data, typename DataCompare >
std::string IntervalTree<Data,DataCompare>::OverlapElements::Locator::_getString () const
{
std::string s = "<" + _TName("OverlapElements::Locator")
+ ">";
@ -252,34 +292,34 @@ namespace Hurricane {
}
template< typename Data >
inline IntervalTree<Data>::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span )
template< typename Data, typename DataCompare >
inline IntervalTree<Data,DataCompare>::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span )
: Collection< IntervalData<Data> >()
, tree_(tree)
, span_(span)
{ }
template< typename Data >
inline IntervalTree<Data>::OverlapElements::OverlapElements ( const OverlapElements& elements )
template< typename Data, typename DataCompare >
inline IntervalTree<Data,DataCompare>::OverlapElements::OverlapElements ( const OverlapElements& elements )
: Collection< IntervalData<Data> >()
, tree_(elements.tree_)
, span_(elements.span_)
{ }
template< typename Data >
Collection< IntervalData<Data> >* IntervalTree<Data>::OverlapElements::getClone () const
template< typename Data, typename DataCompare >
Collection< IntervalData<Data> >* IntervalTree<Data,DataCompare>::OverlapElements::getClone () const
{ return new OverlapElements(*this); }
template< typename Data >
typename IntervalTree<Data>::OverlapElements::Locator* IntervalTree<Data>::OverlapElements::getLocator () const
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::OverlapElements::Locator* IntervalTree<Data,DataCompare>::OverlapElements::getLocator () const
{ return new Locator( tree_, span_ ); }
template< typename Data >
std::string IntervalTree<Data>::OverlapElements::_getString () const
template< typename Data, typename DataCompare >
std::string IntervalTree<Data,DataCompare>::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<Data>::updateChildsVMax ( typename Super::Node* node )
template< typename Data, typename DataCompare >
inline void IntervalTree<Data,DataCompare>::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<Data>& >( node->getValue() ).updateChildsVMax( lchildVMax, rchildVMax );
cdebug_tabw(0,-1);
}
template< typename Data >
void IntervalTree<Data>::postRotateLeft ( typename Super::Node* node )
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::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<Data,DataCompare>::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<Data>::postRotateRight ( typename Super::Node* node )
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::postInsert ( typename Super::Node* node )
{
updateChildsVMax( node );
if (node->getParent()) updateChildsVMax( node->getParent() );
}
template< typename Data >
void IntervalTree<Data>::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<Data>::postRemove ( typename Super::Node* node )
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::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<Data>& >( parent->getValue() ).updateChildsVMax( childVMax, childVMax );
const_cast< IntervalData<Data>& >( parent->getValue() ).updateChildsVMax( childsVMax, childsVMax );
postInsert( parent->getParent() );
}
cdebug_tabw(0,-1);
}
template< typename Data >
size_t IntervalTree<Data>::getThickness () const
template< typename Data, typename DataCompare >
size_t IntervalTree<Data,DataCompare>::getThickness () const
{
cdebug_log(0,0) << "IntervalTree::getThickness() " << std::endl;
@ -381,34 +439,70 @@ namespace Hurricane {
}
template< typename Data >
typename IntervalTree<Data>::overlap_iterator IntervalTree<Data>::beginOverlaps ( const Interval& overlap ) const
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::overlap_iterator
IntervalTree<Data,DataCompare>::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<Data>::OverlapElements IntervalTree<Data>::getOverlaps ( const Interval& overlap ) const
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::OverlapElements
IntervalTree<Data,DataCompare>::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<Data,DataCompare>::checkVMax () const
{
checkVMax( this->getRoot() );
}
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::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.

View File

@ -121,6 +121,10 @@ class JsonOccurrence : public JsonObject {
public: virtual void toData(JsonStack&);
};
typedef std::set<Occurrence> OccurrenceSet;
} // End of Hurricane namespace.

View File

@ -34,9 +34,7 @@
// Third edition, MIT press, 2011, p. 308.
#ifndef HURRICANE_RBTREE_H
#define HURRICANE_RBTREE_H
#pragma once
#include <functional>
#include <fstream>
#include <sstream>
@ -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<Data,Compare>::Node::copy ( const Node* other )
{ value_ = other->value_; }
inline void RbTree<Data,Compare>::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<Data,Compare>::rotateLeft ( typename RbTree<Data,Compare>::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<Data,Compare>::rotateRight ( typename RbTree<Data,Compare>::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() <<std::endl;
cdebug_log(0,-1) << "> 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<Node*>( 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<Data,Compare>::removeRepair ( typename RbTree<Data,Compare>::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<Data,Compare,RbTree>::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

View File

@ -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;

View File

@ -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 );

View File

@ -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

View File

@ -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<Net*>(lhs.getEntity()), static_cast<Net*>(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<Component*>( 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<Net*,NetCompareByName> nets;
for ( Component* component : getComponents() ) {
EquipotentialRelation* relation = EquipotentialRelation::create( this );
set<Net*,NetCompareByName> nets;
set<Occurrence,OccNetCompareByName> deepNets;
for ( const Occurrence& occurrence : getComponents() ) {
Component* component = dynamic_cast<Component*>( 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;

View File

@ -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<EquipotentialRelation*>( property );
if (not relation) return nullptr;
return relation;
}
} // Tramontana namespace.

View File

@ -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 );
}

View File

@ -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 <vector>
#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<Tile*> tiles;
Component* component = dynamic_cast<Component*>( 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.

View File

@ -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<const BasicLayer*> 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<Tile*> tiles;
Component* component = dynamic_cast<Component*>( 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<Tile*> tiles;
// Component* component = dynamic_cast<Component*>( 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() );
}

View File

@ -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&)) );
}
}

View File

@ -133,9 +133,14 @@ namespace Tramontana {
{ }
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;
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;
}

View File

@ -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();
}
}

View File

@ -18,12 +18,10 @@
#pragma once
#include <iostream>
#include <vector>
#include <set>
#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<Occurrence>& 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<Occurrence> _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<Occurrence>& 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.

View File

@ -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);

View File

@ -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;

View File

@ -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.

View File

@ -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<const BasicLayer*>&
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<Element> _tiles;
IntervalTrees _intervalTrees;
TramontanaEngine* _tramontana;
std::vector<const BasicLayer*> _extracteds;
std::vector<Element> _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<const BasicLayer*>& 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 ) );
}

View File

@ -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<Tile*> TileIntv;
typedef IntervalTree<Tile*> TileIntvTree;
typedef IntervalData<Tile*> TileIntv;
typedef IntervalTree<Tile*,TileCompare> TileIntvTree;
} // Tramontana namespace.