diff --git a/tramontana/src/Equipotential.cpp b/tramontana/src/Equipotential.cpp index b2c5141e..6a7f6574 100644 --- a/tramontana/src/Equipotential.cpp +++ b/tramontana/src/Equipotential.cpp @@ -117,9 +117,11 @@ namespace Tramontana { , _name (defaultName) , _type (Net::Type::UNDEFINED) , _direction (Net::Direction::DirUndefined) + , _netCount (0) , _isExternal (false) , _isGlobal (false) , _isAutomatic(false) + , _hasFused (false) { } @@ -194,29 +196,21 @@ namespace Tramontana { void Equipotential::consolidate () { - int containsFused = 0; set nets; for ( Component* component : getComponents() ) { Net* net = component->getNet(); - if (net->isFused ()) containsFused = 1; - if (net->isExternal ()) _isExternal = true; - if (net->isGlobal ()) _isGlobal = true; - if (net->isAutomatic()) _isAutomatic = true; - _type = net->getType(); - _direction |= net->getDirection(); + if (net->isFused()) _hasFused = true; + else { + if (net->isExternal ()) _isExternal = true; + if (net->isGlobal ()) _isGlobal = true; + if (net->isAutomatic()) _isAutomatic = true; + _type = net->getType(); + _direction |= net->getDirection(); + } nets.insert( component->getNet() ); } _name = getString( (*nets.begin())->getName() ); - _name += " [" + getString(nets.size() - containsFused); - if (containsFused) - _name += "+fused"; - _name += "] "; - _name += ((_isExternal ) ? "e" : "-"); - _name += ((_isGlobal ) ? "g" : "-"); - _name += ((_isAutomatic) ? "a" : "-"); - _name += " "; - _name += getString(_type ) + " "; - _name += getString(_direction); + _netCount = nets.size(); } @@ -227,6 +221,20 @@ namespace Tramontana { } + string Equipotential::getFlagsAsString () const + { + string sflags; + sflags += ((_isExternal ) ? "e" : "-"); + sflags += ((_isGlobal ) ? "g" : "-"); + sflags += ((_isAutomatic) ? "a" : "-"); + sflags += " [" + getString( _netCount - ((_hasFused) ? 1 : 0) ); + if (_hasFused) + sflags += "+fused"; + sflags += "] "; + return sflags; + } + + string Equipotential::_getTypeName () const { return "Tramontana::Equipotential"; } @@ -234,9 +242,12 @@ namespace Tramontana { string Equipotential::_getString () const { ostringstream os; - os << "getName() << ">"; + os << ""; return os.str(); } diff --git a/tramontana/src/EquipotentialsModel.cpp b/tramontana/src/EquipotentialsModel.cpp index b27817ab..6f83171e 100644 --- a/tramontana/src/EquipotentialsModel.cpp +++ b/tramontana/src/EquipotentialsModel.cpp @@ -43,7 +43,6 @@ namespace Tramontana { static QFont valueFont = Graphics::getFixedFont ( QFont::Normal, true ); if (role == Qt::FontRole) { - if (index.row() == 0) return QVariant(); switch (index.column()) { case 0: return nameFont; default: return valueFont; @@ -54,8 +53,13 @@ namespace Tramontana { if (not index.isValid()) return QVariant (); if (role == Qt::DisplayRole) { - int row = index.row (); - return QString::fromStdString( _equipotentials[row]->getName() ); + Equipotential* equi = _equipotentials[ index.row() ]; + switch ( index.column() ) { + case 0: return QString::fromStdString( equi->getName() ); + case 1: return QString::fromStdString( equi->getFlagsAsString() ); + case 2: return QString::fromStdString( getString( equi->getType() )); + case 3: return QString::fromStdString( getString( equi->getDirection() )); + } } return QVariant(); } @@ -71,26 +75,20 @@ namespace Tramontana { if (role == Qt::FontRole ) return headerFont; if (role != Qt::DisplayRole) return QVariant(); - - if (section == 0) return QVariant("Equipotential"); - // if (section < _equipotentials->getColumnCount()) - // return _equipotentials->getColumnName( section ); - + if (section == 0) return QVariant( "Name" ); + if (section == 1) return QVariant( "Flags" ); + if (section == 2) return QVariant( "Type" ); + if (section == 3) return QVariant( "Direction" ); return QVariant(); } int EquipotentialsModel::rowCount ( const QModelIndex& parent ) const - { - return _equipotentials.size(); - } + { return _equipotentials.size(); } int EquipotentialsModel::columnCount ( const QModelIndex& parent ) const - { - return 1; - //return (_equipotentials) ? _equipotentials->getColumnCount() : 1; - } + { return 4; } const Equipotential* EquipotentialsModel::getEqui ( int row ) diff --git a/tramontana/src/SweepLine.cpp b/tramontana/src/SweepLine.cpp index 45011625..c40715a1 100644 --- a/tramontana/src/SweepLine.cpp +++ b/tramontana/src/SweepLine.cpp @@ -83,9 +83,9 @@ namespace Tramontana { SweepLine::SweepLine ( TramontanaEngine* tramontana ) - : _tramontana (tramontana) - , _tiles () - , _intervalTree() + : _tramontana (tramontana) + , _tiles () + , _intervalTrees() { } @@ -95,37 +95,79 @@ namespace Tramontana { void SweepLine::run () { - BasicLayer* layer = DataBase::getDB()->getTechnology()->getBasicLayer( "metal1" ); - loadTiles( layer ); + //cerr << "SweepLine::run()" << endl; + //DebugSession::open( 0, 2 ); + loadTiles(); 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; + //cerr << right << setw(10) << 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." + " (for tile: %s)" + , getString(element.getMask()).c_str() + , getString(element.getTile()).c_str() + ) << endl; + continue; + } if (element.isLeftEdge()) { - for ( const TileIntv& overlap : _intervalTree.getOverlaps( + for ( const TileIntv& overlap : intvTree->second.getOverlaps( Interval(tile->getYMin(), tile->getYMax() ))) { - cerr << " | intersect " << overlap.getData() << endl; + //cerr << " | intersect " << overlap.getData() << endl; tile->merge( overlap.getData() ); } - _intervalTree.insert( tileIntv ); + //cerr << " | insert tile" << endl; + intvTree->second.insert( tileIntv ); } else { - _intervalTree.remove( tileIntv ); + //cerr << " | remove tile" << endl; + intvTree->second.remove( tileIntv ); + // if (tile->getId() == 46055) { + // intvTree->second.write( "we_at_remove.gv" ); + // for ( auto tile : intvTree->second.getElements() ) { + // cerr << "| in tree:" << tile << endl; + // } + // } } } + //DebugSession::close(); mergeEquipotentials(); } - void SweepLine::loadTiles ( const BasicLayer* layer ) + void SweepLine::loadTiles () { - cerr << "SweepLine::run()" << endl; + //cerr << "SweepLine::loadTiles()" << endl; + vector extracteds; + for ( const BasicLayer* bl : DataBase::getDB()->getTechnology()->getBasicLayers() ) { + if (bl->getMaterial() == BasicLayer::Material::metal) + extracteds.push_back( bl ); + } + + // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal5" )); + // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal4" )); + // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal3" )); + // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal2" )); + // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal1" )); + // extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "poly" )); + + for ( const BasicLayer* layer : extracteds ) { + _intervalTrees.insert( make_pair( layer->getMask(), TileIntvTree() )); + } + for ( Occurrence occurrence : getCell()->getOccurrencesUnder( getCell()->getBoundingBox() ) ) { + vector tiles; Component* component = dynamic_cast( occurrence.getEntity() ); if (not component) continue; - if (not component->getLayer()->contains(layer)) continue; - Tile* tile = Tile::create( occurrence, layer ); - _tiles.push_back( Element( tile, Tile::LeftEdge ) ); - _tiles.push_back( Element( tile, Tile::RightEdge ) ); + 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() ); } @@ -133,7 +175,7 @@ namespace Tramontana { void SweepLine::mergeEquipotentials () { - cerr << "Tramontana::mergeEquipotentials()" << endl; + //cerr << "SweepLine::mergeEquipotentials()" << endl; Tile::timeTick(); for ( Tile* tile : Tile::getAllTiles() ) { tile->getRoot( Tile::MergeEqui ); diff --git a/tramontana/src/Tile.cpp b/tramontana/src/Tile.cpp index 4cf692e6..550778cb 100644 --- a/tramontana/src/Tile.cpp +++ b/tramontana/src/Tile.cpp @@ -108,7 +108,7 @@ namespace Tramontana { if (not component->getLayer()->contains(layer)) { cerr << Error( "Tile::create(): Component layer does not contains \"%s\".\n" " (%s)" - , getString(layer->getName()).c_str() + , getString(layer).c_str() , getString(occurrence).c_str() ) << endl; return nullptr; diff --git a/tramontana/src/TramontanaEngine.cpp b/tramontana/src/TramontanaEngine.cpp index 852f8d62..bf5c8490 100644 --- a/tramontana/src/TramontanaEngine.cpp +++ b/tramontana/src/TramontanaEngine.cpp @@ -145,11 +145,14 @@ namespace Tramontana { void TramontanaEngine::extract () { - cerr << "TramontanaEngine::extract() called on " << getCell() << endl; + cmess1 << " o Extracting " << getCell() << endl; + startMeasures(); SweepLine sweepLine ( this ); sweepLine.run(); consolidate(); - showEquipotentials(); + //showEquipotentials(); + stopMeasures(); + printMeasures(); } @@ -167,7 +170,7 @@ namespace Tramontana { void TramontanaEngine::consolidate () { - cerr << "Tramontana::consolidate()" << endl; + //cerr << "Tramontana::consolidate()" << endl; for ( Equipotential* equi : _equipotentials ) equi->consolidate(); } diff --git a/tramontana/src/tramontana/Equipotential.h b/tramontana/src/tramontana/Equipotential.h index 57c95500..f8f9bb5b 100644 --- a/tramontana/src/tramontana/Equipotential.h +++ b/tramontana/src/tramontana/Equipotential.h @@ -49,31 +49,34 @@ 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; - inline bool hasComponent ( Component* ) const; - void add ( Component* ); - void add ( Occurrence ); - void merge ( Equipotential* ); - void consolidate (); - void clear (); - inline const ComponentSet& getComponents () const; - inline const std::vector& getChilds () const; - Record* _getRecord () const; - std::string _getString () const; - std::string _getTypeName () const; - protected: - virtual void _postCreate (); - virtual void _preDestroy (); - private: - Equipotential ( Cell* ); - ~Equipotential (); - private: - Equipotential ( const Equipotential& ) = delete; - Equipotential& operator= ( const Equipotential& ) = delete; + static Equipotential* create ( Cell* ); + inline bool isEmpty () const; + virtual Cell* getCell () const; + virtual Box getBoundingBox () const; + inline std::string getName () const; + std::string getFlagsAsString () const; + inline Net::Type getType () const; + inline Net::Direction getDirection () const; + inline bool hasComponent ( Component* ) const; + void add ( Component* ); + void add ( Occurrence ); + void merge ( Equipotential* ); + void consolidate (); + void clear (); + inline const ComponentSet& getComponents () const; + inline const std::vector& getChilds () const; + Record* _getRecord () const; + std::string _getString () const; + std::string _getTypeName () const; + protected: + virtual void _postCreate (); + virtual void _preDestroy (); + private: + Equipotential ( Cell* ); + ~Equipotential (); + private: + Equipotential ( const Equipotential& ) = delete; + Equipotential& operator= ( const Equipotential& ) = delete; private: Cell* _owner; Box _boundingBox; @@ -82,9 +85,11 @@ namespace Tramontana { std::string _name; Net::Type _type; Net::Direction _direction; + uint32_t _netCount; bool _isExternal; bool _isGlobal; bool _isAutomatic; + bool _hasFused; }; @@ -92,6 +97,8 @@ namespace Tramontana { inline bool Equipotential::isEmpty () const { return _components.empty() and _childs.empty(); } inline const ComponentSet& Equipotential::getComponents () const { return _components; } inline std::string Equipotential::getName () const { return _name; } + inline Net::Type Equipotential::getType () const { return _type; } + inline Net::Direction Equipotential::getDirection () const { return _direction; } inline const std::vector& Equipotential::getChilds () const { return _childs; } inline bool Equipotential::hasComponent ( Component* component ) const diff --git a/tramontana/src/tramontana/SweepLine.h b/tramontana/src/tramontana/SweepLine.h index 1e3b441d..0fb6d0eb 100644 --- a/tramontana/src/tramontana/SweepLine.h +++ b/tramontana/src/tramontana/SweepLine.h @@ -19,6 +19,7 @@ #pragma once #include #include +#include #include "hurricane/BasicLayer.h" namespace Hurricane { class Net; @@ -33,22 +34,27 @@ namespace Tramontana { using Hurricane::Box; using Hurricane::DbU; using Hurricane::Cell; + using Hurricane::Layer; + using Hurricane::BasicLayer; // ------------------------------------------------------------------- // Class : "Tramontana::SweepLine". class SweepLine { + private: + typedef std::map IntervalTrees; private: class Element { public: - inline Element ( Tile*, uint32_t flags ); - inline bool operator< ( const Element& ) const; - inline bool isLeftEdge () const; - inline Tile* getTile () const; - inline DbU::Unit getX () const; - inline DbU::Unit getY () const; - inline DbU::Unit getId () const; + inline Element ( Tile*, uint32_t flags ); + inline bool operator< ( const Element& ) const; + inline bool isLeftEdge () const; + inline Tile* getTile () const; + inline DbU::Unit getX () const; + inline DbU::Unit getY () const; + inline DbU::Unit getId () const; + inline Layer::Mask getMask () const; private: Tile* _tile; uint32_t _flags; @@ -58,7 +64,7 @@ namespace Tramontana { ~SweepLine (); inline Cell* getCell (); void run (); - void loadTiles ( const BasicLayer* ); + void loadTiles (); void mergeEquipotentials (); Record* _getRecord () const; std::string _getString () const; @@ -69,22 +75,24 @@ namespace Tramontana { private: TramontanaEngine* _tramontana; std::vector _tiles; - TileIntvTree _intervalTree; + IntervalTrees _intervalTrees; }; // SweepLine::Element. - inline SweepLine::Element::Element ( Tile* tile, uint32_t flags ) : _tile(tile), _flags(flags) { } - inline bool SweepLine::Element::isLeftEdge () const { return _flags & Tile::LeftEdge; } - inline Tile* SweepLine::Element::getTile () const { return _tile; } - inline DbU::Unit SweepLine::Element::getX () const { return isLeftEdge() ? _tile->getLeftEdge() : _tile->getRightEdge(); } - inline DbU::Unit SweepLine::Element::getY () const { return _tile->getBoundingBox().getYMin(); } - inline DbU::Unit SweepLine::Element::getId () const { return _tile->getId(); } + inline SweepLine::Element::Element ( Tile* tile, uint32_t flags ) : _tile(tile), _flags(flags) { } + inline bool SweepLine::Element::isLeftEdge () const { return _flags & Tile::LeftEdge; } + inline Tile* SweepLine::Element::getTile () const { return _tile; } + inline DbU::Unit SweepLine::Element::getX () const { return isLeftEdge() ? _tile->getLeftEdge() : _tile->getRightEdge(); } + inline DbU::Unit SweepLine::Element::getY () const { return _tile->getBoundingBox().getYMin(); } + inline DbU::Unit SweepLine::Element::getId () const { return _tile->getId(); } + inline Layer::Mask SweepLine::Element::getMask () const { return _tile->getMask(); } inline bool SweepLine::Element::operator< ( const Element& rhs ) const { if (getX() != rhs.getX()) return (getX() < rhs.getX()); if (getY() != rhs.getY()) return (getY() < rhs.getY()); + if (getMask() != rhs.getMask()) return (getMask() < rhs.getMask()); return getId() < rhs.getId(); } diff --git a/tramontana/src/tramontana/Tile.h b/tramontana/src/tramontana/Tile.h index 652d346a..a8bf7db9 100644 --- a/tramontana/src/tramontana/Tile.h +++ b/tramontana/src/tramontana/Tile.h @@ -68,7 +68,8 @@ namespace Tramontana { Tile* getRoot ( uint32_t flags=Compress ); inline Component* getComponent () const; inline Occurrence getOccurrence () const; - inline const BasicLayer* getLayer () const; + inline Layer::Mask getMask () const; + inline const BasicLayer* getLayer () const; inline const Box& getBoundingBox () const; inline Equipotential* getEquipotential () const; inline DbU::Unit getLeftEdge () const; @@ -110,6 +111,7 @@ namespace Tramontana { inline unsigned int Tile::getId () const { return getComponent()->getId(); } inline Component* Tile::getComponent () const { return dynamic_cast( _occurrence.getEntity() ); } inline Occurrence Tile::getOccurrence () const { return _occurrence; } + inline Layer::Mask Tile::getMask () const { return _layer->getMask(); } inline const BasicLayer* Tile::getLayer () const { return _layer; } inline const Box& Tile::getBoundingBox () const { return _boundingBox; } inline Equipotential* Tile::getEquipotential () const { return _equipotential; }