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:
parent
6361ad4ca0
commit
518a376c01
|
@ -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() ) {
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -146,6 +146,9 @@ namespace Hurricane {
|
|||
}
|
||||
|
||||
|
||||
string& split ( std::string& );
|
||||
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -121,6 +121,10 @@ class JsonOccurrence : public JsonObject {
|
|||
public: virtual void toData(JsonStack&);
|
||||
};
|
||||
|
||||
|
||||
typedef std::set<Occurrence> OccurrenceSet;
|
||||
|
||||
|
||||
} // End of Hurricane namespace.
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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.
|
|
@ -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() );
|
||||
}
|
||||
|
||||
|
|
|
@ -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&)) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
|
@ -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 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue