diff --git a/cumulus/src/plugins/chip/Chip.py b/cumulus/src/plugins/chip/Chip.py index 46e62b2e..a5a58063 100644 --- a/cumulus/src/plugins/chip/Chip.py +++ b/cumulus/src/plugins/chip/Chip.py @@ -152,7 +152,8 @@ class PlaceRoute ( object ): ht = clocktree.ClockTree.HTree.create( self.conf, coreCell, coreCk, coreCell.getAbutmentBox() ) ht.addCloned( self.conf.cell ) ht.addCloned( self.conf.corona ) - etesian = Etesian.EtesianEngine.create( coreCell ) + etesian = Etesian.EtesianEngine.create( self.conf.corona ) + etesian.setBlock( self.conf.icore ) etesian.setViewer( self.conf.viewer ) etesian.place() etesian.destroy() @@ -161,7 +162,8 @@ class PlaceRoute ( object ): ht.route() ht.save( self.conf.cell ) else: - etesian = Etesian.EtesianEngine.create( coreCell ) + etesian = Etesian.EtesianEngine.create( self.conf.corona ) + etesian.setBlock( self.conf.icore ) etesian.place() etesian.destroy() return diff --git a/etesian/src/AddFeeds.cpp b/etesian/src/AddFeeds.cpp index 40c91cd6..ab6f7f9f 100644 --- a/etesian/src/AddFeeds.cpp +++ b/etesian/src/AddFeeds.cpp @@ -210,7 +210,7 @@ namespace { if (feed == NULL) break; } - Instance::create ( getEtesian()->getCell() + Instance::create ( getEtesian()->getBlockCell() , getEtesian()->getFeedCells().getUniqueInstanceName().c_str() , feed , getTransformation( feed->getAbutmentBox() @@ -245,7 +245,7 @@ namespace { SliceHoles::SliceHoles ( EtesianEngine* etesian ) : _etesian (etesian) - , _cellAb (etesian->getCell()->getAbutmentBox()) + , _cellAb (etesian->getBlockCell()->getAbutmentBox()) , _sliceHeight(_etesian->getSliceHeight()) , _slices () { @@ -308,10 +308,10 @@ namespace Etesian { _ySpinSet = false; _yspinSlice0 = 0; - Box topCellAb = getCell()->getAbutmentBox(); + Box topCellAb = getBlockCell()->getAbutmentBox(); if (not topCellAb.isEmpty()) { - for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) + for ( Occurrence occurrence : getBlockCell()->getLeafInstanceOccurrences() ) { Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); @@ -325,7 +325,7 @@ namespace Etesian { _ySpinSet = true; - int islice = (instanceAb.getYMin() - getCell()->getAbutmentBox().getYMin()) / getSliceHeight(); + int islice = (instanceAb.getYMin() - getBlockCell()->getAbutmentBox().getYMin()) / getSliceHeight(); switch ( instanceTransf.getOrientation() ) { case Transformation::Orientation::ID: @@ -366,11 +366,11 @@ namespace Etesian { UpdateSession::open(); SliceHoles sliceHoles ( this ); - Box topCellAb = getCell()->getAbutmentBox(); + Box topCellAb = getBlockCell()->getAbutmentBox(); sliceHoles.setSpinSlice0( _yspinSlice0 ); - for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) + for ( Occurrence occurrence : getBlockCell()->getLeafInstanceOccurrences() ) { Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index f06848bc..d077cfa6 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -31,6 +31,7 @@ #include "hurricane/Layer.h" #include "hurricane/Net.h" #include "hurricane/Pad.h" +#include "hurricane/Pin.h" #include "hurricane/Plug.h" #include "hurricane/Cell.h" #include "hurricane/Occurrence.h" @@ -208,6 +209,7 @@ namespace Etesian { using Hurricane::Layer; using Hurricane::Cell; using Hurricane::Instance; + using Hurricane::Pin; using Hurricane::RoutingPad; using Hurricane::Net; using Hurricane::Occurrence; @@ -254,7 +256,9 @@ namespace Etesian { EtesianEngine::EtesianEngine ( Cell* cell ) : Super (cell) , _configuration(new Configuration()) + , _block (NULL) , _placed (false) + , _ySpinSet (false) , _flatDesign (false) , _surface () , _circuit () @@ -426,7 +430,7 @@ namespace Etesian { UpdateSession::open(); vector feedOccurrences; - for( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) + for( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) { dots.dot(); @@ -444,7 +448,7 @@ namespace Etesian { for ( auto ioccurrence : feedOccurrences ) { cerr << " Destroy: " << ioccurrence.getCompactString() << endl; - Instance* instance = static_cast(ioccurrence.getEntity()); + Instance* instance = static_cast(ioccurrence.getEntity()); instance->destroy(); } UpdateSession::close(); @@ -473,7 +477,7 @@ namespace Etesian { if (not cmess2.enabled()) dots.disable(); size_t instancesNb = 0; - for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) { + for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) { Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); @@ -497,11 +501,14 @@ namespace Etesian { cmess1 << " - Converting " << instancesNb << " instances" << endl; cout.flush(); - - Box topAb = getCell()->getAbutmentBox(); + + Box topAb = getBlockCell()->getAbutmentBox(); + Transformation topTransformation; + if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation(); + topTransformation.applyOn( topAb ); UpdateSession::open(); - for ( Occurrence occurrence : getCell()->getNonLeafInstanceOccurrences() ) + for ( Occurrence occurrence : getBlockCell()->getNonLeafInstanceOccurrences() ) { Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); @@ -530,10 +537,10 @@ namespace Etesian { cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); - getCell()->flattenNets( Cell::Flags::NoClockFlatten ); + getCell()->flattenNets( getBlockInstance(), Cell::Flags::NoClockFlatten ); index_t instanceId = 0; - for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) + for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) { Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); @@ -618,8 +625,23 @@ namespace Etesian { nets[netId] = temporary_net( netId, 1 ); //cerr << "+ " << net << endl; + + for ( Pin* pin : net->getPins() ) { + //cerr << "Outside Pin: " << pin << endl; + // For Gabriel Gouvine : the position of this pin should be added as a fixed + // attractor in Coloquinte. May be outside the placement area. + } for ( RoutingPad* rp : net->getRoutingPads() ) { + if (getBlockInstance() and (rp->getOccurrence().getPath().getHeadInstance() != getBlockInstance())) { + //cerr << "Outside RP: " << rp << endl; + // For Gabriel Gouvine : if there are multiple blocks (i.e. we have a true + // floorplan, there may be RoutingPad that are elsewhere. We should check + // that the RP is placed or is inside a define area (the abutment box of + // it's own block). No example yet of that case, though. + continue; + } + string insName = extractInstanceName( rp ); Point offset = extractRpOffset ( rp ); @@ -640,10 +662,10 @@ namespace Etesian { } dots.finish( Dots::Reset ); - _surface = box( (int_t)(getCell()->getAbutmentBox().getXMin() / vpitch) - , (int_t)(getCell()->getAbutmentBox().getXMax() / vpitch) - , (int_t)(getCell()->getAbutmentBox().getYMin() / hpitch) - , (int_t)(getCell()->getAbutmentBox().getYMax() / hpitch) + _surface = box( (int_t)(topAb.getXMin() / vpitch) + , (int_t)(topAb.getXMax() / vpitch) + , (int_t)(topAb.getYMin() / hpitch) + , (int_t)(topAb.getYMax() / hpitch) ); _circuit = netlist( instances, nets, pins ); _circuit.selfcheck(); @@ -888,14 +910,16 @@ namespace Etesian { void EtesianEngine::place () { - if(getCell()->isPlaced()){ - cmess2 << Warning("The cell is already placed; returning") << std::endl; - return; + if (getBlockCell()->isPlaced()) { + cerr << Warning( "EtesianEngine::place(): The cell \"%s\" is already placed (aborting)" + , getString(getBlockCell()->getName()).c_str() + ) << std::endl; + return; } - getCell()->uniquify(); + getBlockCell()->uniquify(); getConfiguration()->print( getCell() ); - if (getCell()->getAbutmentBox().isEmpty()) setDefaultAb(); + if (getBlockCell()->getAbutmentBox().isEmpty()) setDefaultAb(); findYSpin(); toColoquinte(); @@ -919,44 +943,41 @@ namespace Etesian { int detailedIterations, detailedEffort; unsigned globalOptions=0, detailedOptions=0; - if(placementUpdate == UpdateAll){ - globalOptions |= (UpdateUB | UpdateLB); - detailedOptions |= UpdateDetailed; + if (placementUpdate == UpdateAll) { + globalOptions |= (UpdateUB | UpdateLB); + detailedOptions |= UpdateDetailed; } - else if(placementUpdate == LowerBound){ + else if (placementUpdate == LowerBound) { globalOptions |= UpdateLB; } - if(densityConf == ForceUniform) + if (densityConf == ForceUniform) globalOptions |= ForceUniformDensity; - if(placementEffort == Fast){ - minPenaltyIncrease = 0.005f; - maxPenaltyIncrease = 0.08f; - targetImprovement = 0.05f; // 5/100 per iteration - detailedIterations = 1; - detailedEffort = 0; - } - else if(placementEffort == Standard){ - minPenaltyIncrease = 0.001f; - maxPenaltyIncrease = 0.04f; - targetImprovement = 0.02f; // 2/100 per iteration - detailedIterations = 2; - detailedEffort = 1; - } - else if(placementEffort == High){ - minPenaltyIncrease = 0.0005f; - maxPenaltyIncrease = 0.02f; - targetImprovement = 0.01f; // 1/100 per iteration - detailedIterations = 4; - detailedEffort = 2; - } - else{ - minPenaltyIncrease = 0.0002f; - maxPenaltyIncrease = 0.01f; - targetImprovement = 0.005f; // 5/1000 per iteration - detailedIterations = 7; - detailedEffort = 3; + if (placementEffort == Fast) { + minPenaltyIncrease = 0.005f; + maxPenaltyIncrease = 0.08f; + targetImprovement = 0.05f; // 5/100 per iteration + detailedIterations = 1; + detailedEffort = 0; + } else if (placementEffort == Standard) { + minPenaltyIncrease = 0.001f; + maxPenaltyIncrease = 0.04f; + targetImprovement = 0.02f; // 2/100 per iteration + detailedIterations = 2; + detailedEffort = 1; + } else if (placementEffort == High) { + minPenaltyIncrease = 0.0005f; + maxPenaltyIncrease = 0.02f; + targetImprovement = 0.01f; // 1/100 per iteration + detailedIterations = 4; + detailedEffort = 2; + } else { + minPenaltyIncrease = 0.0002f; + maxPenaltyIncrease = 0.01f; + targetImprovement = 0.005f; // 5/1000 per iteration + detailedIterations = 7; + detailedEffort = 3; } cmess1 << " o Global placement." << endl; @@ -1014,6 +1035,37 @@ namespace Etesian { } +#if DISABLED + void EtesianEngine::place ( Instance* instance ) + { + setBlock( instance ); + + if (getCell()->getAbutmentBox().isEmpty()) { + cmess2 << Error( "EtesianEngine::place(): Cell \"%s\" must have an abutment box." + , getString(getCell()->getName()).c_str() + ) << std::endl; + return; + } + if (getBlockCell()->getAbutmentBox().isEmpty()) { + cmess2 << Error( "EtesianEngine::place(): Instance \"%s\" must have an abutment box." + , getString(instance->getName()).c_str() + ) << std::endl; + return; + } + if(getBlockCell()->isPlaced()){ + cmess2 << Error( "EtesianEngine::place(): The instance \"%s\" is already placed." + , getString(instance->getName()).c_str() + ) << std::endl; + return; + } + getBlockCell()->uniquify(); + + getConfiguration()->print( getCell() ); + findYSpin(); + } +#endif + + void EtesianEngine::_progressReport1 ( string label ) const { size_t w = label.size(); @@ -1054,7 +1106,12 @@ namespace Etesian { { UpdateSession::open(); - for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) + Box topAb = getBlockCell()->getAbutmentBox(); + Transformation topTransformation; + if (getBlockInstance()) topTransformation = getBlockInstance()->getTransformation(); + topTransformation.invert(); + + for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences(getBlockInstance()) ) { DbU::Unit hpitch = getHorizontalPitch(); DbU::Unit vpitch = getVerticalPitch(); @@ -1083,6 +1140,7 @@ namespace Etesian { // This is temporary as it's not trans-hierarchic: we ignore the positions // of all the intermediary instances. + topTransformation.applyOn( trans ); instance->setTransformation( trans ); instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); } diff --git a/etesian/src/PyEtesianEngine.cpp b/etesian/src/PyEtesianEngine.cpp index aff4b959..a62dd36a 100644 --- a/etesian/src/PyEtesianEngine.cpp +++ b/etesian/src/PyEtesianEngine.cpp @@ -15,6 +15,7 @@ #include "hurricane/isobar/PyCell.h" +#include "hurricane/isobar/PyInstance.h" #include "hurricane/viewer/PyCellViewer.h" #include "hurricane/Cell.h" #include "hurricane/viewer/ExceptionWidget.h" @@ -48,6 +49,8 @@ namespace Etesian { using Isobar::ParseTwoArg; using Isobar::PyCell; using Isobar::PyCell_Link; + using Isobar::PyInstance; + using Isobar::PyInstance_Link; using Isobar::PyCellViewer; using Isobar::PyTypeCellViewer; using CRL::PyToolEngine; @@ -149,6 +152,22 @@ extern "C" { } + static PyObject* PyEtesianEngine_setBlock ( PyEtesianEngine *self, PyObject* args ) + { + cdebug_log(34,0) << "PyEtesianEngine_setBlock()" << endl; + HTRY + METHOD_HEAD ( "EtesianEngine.setBlock()" ) + + PyInstance* pyInstance = NULL; + if (not ParseOneArg("EtesianEngine.setBlock",args,INST_ARG,(PyObject**)&pyInstance) ) + return NULL; + + etesian->setBlock( PYINSTANCE_O(pyInstance) ); + HCATCH + Py_RETURN_NONE; + } + + static PyObject* PyEtesianEngine_place ( PyEtesianEngine* self ) { cdebug_log(34,0) << "PyEtesianEngine_place()" << endl; @@ -183,6 +202,8 @@ extern "C" { , "Associate a Viewer to this EtesianEngine." } , { "selectBloat" , (PyCFunction)PyEtesianEngine_selectBloat , METH_VARARGS , "Select the Cell bloating profile." } + , { "setBlock" , (PyCFunction)PyEtesianEngine_setBlock , METH_VARARGS + , "Set the sub-block (Instance) to place." } , { "setDefaultAb" , (PyCFunction)PyEtesianEngine_setDefaultAb , METH_NOARGS , "Compute and set the abutment box using the aspect ratio and the space margin." } , { "place" , (PyCFunction)PyEtesianEngine_place , METH_NOARGS diff --git a/etesian/src/etesian/EtesianEngine.h b/etesian/src/etesian/EtesianEngine.h index f246530d..f6d2b4f3 100644 --- a/etesian/src/etesian/EtesianEngine.h +++ b/etesian/src/etesian/EtesianEngine.h @@ -77,19 +77,18 @@ namespace Etesian { inline const FeedCells& getFeedCells () const; inline Hurricane::CellViewer* getViewer () const; inline void setViewer ( Hurricane::CellViewer* ); - + inline Cell* getBlockCell () const; + inline Instance* getBlockInstance () const; + inline void setBlock ( Instance* ); void setDefaultAb (); void resetPlacement (); void toColoquinte (); - void preplace (); void roughLegalize ( float minDisruption, unsigned options ); void globalPlace ( float initPenalty, float minDisruption, float targetImprovement, float minInc, float maxInc, unsigned options=0 ); void detailedPlace ( int iterations, int effort, unsigned options=0 ); void feedRoutingBack (); - void place (); - inline void useFeed ( Cell* ); size_t findYSpin (); void addFeeds (); @@ -102,6 +101,7 @@ namespace Etesian { static Name _toolName; protected: Configuration* _configuration; + Instance* _block; bool _placed; bool _ySpinSet; bool _flatDesign; @@ -151,6 +151,9 @@ namespace Etesian { inline const FeedCells& EtesianEngine::getFeedCells () const { return _feedCells; } inline void EtesianEngine::selectBloat ( std::string profile ) { _bloatCells.select(profile); } + inline Cell* EtesianEngine::getBlockCell () const { return (_block) ? _block->getMasterCell() : getCell(); } + inline Instance* EtesianEngine::getBlockInstance () const { return _block; } + inline void EtesianEngine::setBlock ( Instance* block ) { _block = block; } // Variables. extern const char* missingEtesian; diff --git a/hurricane/src/hurricane/CellCollections.cpp b/hurricane/src/hurricane/CellCollections.cpp index 7b3a4309..a398124b 100644 --- a/hurricane/src/hurricane/CellCollections.cpp +++ b/hurricane/src/hurricane/CellCollections.cpp @@ -994,72 +994,46 @@ class Cell_OccurrencesUnder : public Collection { }; -// **************************************************************************************************** -// Cell_LeafInstanceOccurrences declaration -// **************************************************************************************************** + +// ------------------------------------------------------------------- +// class : "Cell_LeafInstanceOccurrences". class Cell_LeafInstanceOccurrences : public Collection { -// ***************************************************************** - -// Types -// ***** - - public: typedef Collection Inherit; - - public: class Locator : public Hurricane::Locator { - // ********************************************************* - - public: typedef Hurricane::Locator Inherit; - - private: const Cell* _cell; - private: int _state; - private: InstanceLocator _leafInstanceLocator; - private: InstanceLocator _nonLeafInstanceLocator; - private: OccurrenceLocator _occurrenceLocator; - - public: Locator(const Cell* cell = NULL); - public: Locator(const Locator& locator); - - public: Locator& operator=(const Locator& locator); - - public: virtual Occurrence getElement() const; - public: virtual Hurricane::Locator* getClone() const; - - public: virtual bool isValid() const; - - public: virtual void progress(); - - public: virtual string _getString() const; + public: + typedef Collection Inherit; + public: + class Locator : public Hurricane::Locator { + public: + typedef Hurricane::Locator Inherit; + public: + Locator ( const Cell* cell=NULL, const Instance* topInstance=NULL ); + Locator ( const Locator& ); + Locator& operator= ( const Locator& ); + virtual Occurrence getElement () const; + virtual Hurricane::Locator* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + private: + const Cell* _cell; + const Instance* _topInstance; + int _state; + InstanceLocator _leafInstanceLocator; + InstanceLocator _nonLeafInstanceLocator; + OccurrenceLocator _occurrenceLocator; }; -// Attributes -// ********** - - private: const Cell* _cell; - -// Constructors -// ************ - - public: Cell_LeafInstanceOccurrences(const Cell* cell = NULL); - public: Cell_LeafInstanceOccurrences(const Cell_LeafInstanceOccurrences& occurrences); - -// Operators -// ********* - - public: Cell_LeafInstanceOccurrences& operator=(const Cell_LeafInstanceOccurrences& occurrences); - -// Accessors -// ********* - - public: virtual Collection* getClone() const; - public: virtual Hurricane::Locator* getLocator() const; - -// Others -// ****** - - public: virtual string _getString() const; - + public: + Cell_LeafInstanceOccurrences ( const Cell* cell=NULL, const Instance* topInstance=NULL ); + Cell_LeafInstanceOccurrences ( const Cell_LeafInstanceOccurrences& ); + Cell_LeafInstanceOccurrences& operator= ( const Cell_LeafInstanceOccurrences& ); + virtual Collection* getClone () const; + virtual Hurricane::Locator* getLocator () const; + virtual string _getString () const; + private: + const Cell* _cell; + const Instance* _topInstance; }; @@ -1136,71 +1110,46 @@ class Cell_LeafInstanceOccurrencesUnder : public Collection { }; -// **************************************************************************************************** -// Cell_NonLeafInstanceOccurrences declaration -// **************************************************************************************************** + +// ------------------------------------------------------------------- +// class : "Cell_NonLeafInstanceOccurrences". class Cell_NonLeafInstanceOccurrences : public Collection { -// ******************************************************************** - -// Types -// ***** - - public: typedef Collection Inherit; - - public: class Locator : public Hurricane::Locator { - // ************************************************************ - - public: typedef Hurricane::Locator Inherit; - - private: const Cell* _cell; - private: int _state; - private: InstanceLocator _nonLeafInstanceLocator; - private: OccurrenceLocator _occurrenceLocator; - - public: Locator(const Cell* cell = NULL); - public: Locator(const Locator& locator); - - public: Locator& operator=(const Locator& locator); - - public: virtual Occurrence getElement() const; - public: virtual Hurricane::Locator* getClone() const; - - public: virtual bool isValid() const; - - public: virtual void progress(); - - public: virtual string _getString() const; + public: + typedef Collection Inherit; + public: + class Locator : public Hurricane::Locator { + public: + typedef Hurricane::Locator Inherit; + public: + Locator ( const Cell* cell=NULL, const Instance* topInstance=NULL ); + Locator ( const Locator& ); + Locator& operator= ( const Locator& ); + virtual Occurrence getElement () const; + virtual Hurricane::Locator* getClone () const; + virtual bool isValid () const; + virtual void progress (); + void _nonLeafProgress ( bool inCTOR ); + virtual string _getString () const; + private: + const Cell* _cell; + const Instance* _topInstance; + int _state; + InstanceLocator _nonLeafInstanceLocator; + OccurrenceLocator _occurrenceLocator; }; -// Attributes -// ********** - - private: const Cell* _cell; - -// Constructors -// ************ - - public: Cell_NonLeafInstanceOccurrences(const Cell* cell = NULL); - public: Cell_NonLeafInstanceOccurrences(const Cell_NonLeafInstanceOccurrences& occurrences); - -// Operators -// ********* - - public: Cell_NonLeafInstanceOccurrences& operator=(const Cell_NonLeafInstanceOccurrences& occurrences); - -// Accessors -// ********* - - public: virtual Collection* getClone() const; - public: virtual Hurricane::Locator* getLocator() const; - -// Others -// ****** - - public: virtual string _getString() const; - + public: + Cell_NonLeafInstanceOccurrences ( const Cell* cell=NULL, const Instance* topInstance=NULL ); + Cell_NonLeafInstanceOccurrences ( const Cell_NonLeafInstanceOccurrences& ); + Cell_NonLeafInstanceOccurrences& operator= ( const Cell_NonLeafInstanceOccurrences& ); + virtual Collection* getClone () const; + virtual Hurricane::Locator* getLocator () const; + virtual string _getString () const; + private: + const Cell* _cell; + const Instance* _topInstance; }; @@ -2022,10 +1971,10 @@ Occurrences Cell::getTerminalInstanceOccurrencesUnder(const Box& area) const return Cell_TerminalInstanceOccurrencesUnder(this, area); } -Occurrences Cell::getLeafInstanceOccurrences() const -// *********************************************** +Occurrences Cell::getLeafInstanceOccurrences( const Instance* topInstance ) const +// ****************************************************************************** { - return Cell_LeafInstanceOccurrences(this); + return Cell_LeafInstanceOccurrences( this, topInstance ); } Occurrences Cell::getLeafInstanceOccurrencesUnder(const Box& area) const @@ -2034,10 +1983,10 @@ Occurrences Cell::getLeafInstanceOccurrencesUnder(const Box& area) const return Cell_LeafInstanceOccurrencesUnder(this, area); } -Occurrences Cell::getNonLeafInstanceOccurrences() const -// *********************************************** +Occurrences Cell::getNonLeafInstanceOccurrences( const Instance* topInstance ) const +// ********************************************************************************* { - return Cell_NonLeafInstanceOccurrences(this); + return Cell_NonLeafInstanceOccurrences(this,topInstance); } Occurrences Cell::getComponentOccurrences(const Layer::Mask& mask) const @@ -3203,189 +3152,194 @@ string Cell_OccurrencesUnder::Locator::_getString() const return s; } -// **************************************************************************************************** -// Cell_LeafInstanceOccurrences implementation -// **************************************************************************************************** -Cell_LeafInstanceOccurrences::Cell_LeafInstanceOccurrences(const Cell* cell) -// ******************************************************************************* -: Inherit(), - _cell(cell) -{ -} +// ------------------------------------------------------------------- +// Class : "Cell_LeafInstanceOccurrences". -Cell_LeafInstanceOccurrences::Cell_LeafInstanceOccurrences(const Cell_LeafInstanceOccurrences& occurrences) -// **************************************************************************************************** -: Inherit(), - _cell(occurrences._cell) -{ -} +Cell_LeafInstanceOccurrences::Cell_LeafInstanceOccurrences ( const Cell* cell, const Instance* topInstance ) + : Inherit() + , _cell (cell) + , _topInstance(topInstance) +{ } -Cell_LeafInstanceOccurrences& Cell_LeafInstanceOccurrences::operator=(const Cell_LeafInstanceOccurrences& occurrences) -// **************************************************************************************************** -{ - _cell = occurrences._cell; - return *this; -} -Collection* Cell_LeafInstanceOccurrences::getClone() const -// ********************************************************************* -{ - return new Cell_LeafInstanceOccurrences(*this); -} +Cell_LeafInstanceOccurrences::Cell_LeafInstanceOccurrences ( const Cell_LeafInstanceOccurrences& occurrences ) + : Inherit() + , _cell (occurrences._cell) + , _topInstance(occurrences._topInstance) +{ } -Locator* Cell_LeafInstanceOccurrences::getLocator() const -// ******************************************************************** -{ - return new Locator(_cell); -} -string Cell_LeafInstanceOccurrences::_getString() const -// ******************************************************* +Cell_LeafInstanceOccurrences& Cell_LeafInstanceOccurrences::operator= ( const Cell_LeafInstanceOccurrences& occurrences ) { - string s = "<" + _TName("Cell::LeafInstanceOccurrences"); - if (_cell) s += " " + getString(_cell); - s += ">"; - return s; + _cell = occurrences._cell; + _topInstance = occurrences._topInstance; + return *this; } +Collection* Cell_LeafInstanceOccurrences::getClone () const +{ return new Cell_LeafInstanceOccurrences( *this ); } -// **************************************************************************************************** -// Cell_LeafInstanceOccurrences::Locator implementation -// **************************************************************************************************** -Cell_LeafInstanceOccurrences::Locator::Locator(const Cell* cell) -// **************************************************************** -: Inherit(), - _cell(cell), - _state(0), - _leafInstanceLocator(), - _nonLeafInstanceLocator(), - _occurrenceLocator() +Locator* Cell_LeafInstanceOccurrences::getLocator () const +{ return new Locator ( _cell, _topInstance ); } + + +string Cell_LeafInstanceOccurrences::_getString () const { - if (_cell) { - _leafInstanceLocator = _cell->getLeafInstances().getLocator(); - if (_leafInstanceLocator.isValid()) - _state = 1; - else { - _nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator(); - while (!_state && _nonLeafInstanceLocator.isValid()) { + string s = "<" + _TName("Cell::LeafInstanceOccurrences"); + if (_cell) s += " " + getString(_cell); + if (_topInstance) s += " " + getString(_topInstance); + s += ">"; + return s; +} + + +// ------------------------------------------------------------------- +// Class : "Cell_LeafInstanceOccurrences::Locator". + +Cell_LeafInstanceOccurrences::Locator::Locator ( const Cell* cell, const Instance* topInstance ) + : Inherit() + , _cell (cell) + , _topInstance (topInstance) + , _state (0) + , _leafInstanceLocator () + , _nonLeafInstanceLocator() + , _occurrenceLocator () +{ + if (not _cell) return; + + if (not _topInstance) _leafInstanceLocator = _cell->getLeafInstances().getLocator(); + + if (_leafInstanceLocator.isValid()) + _state = 1; + else { + _nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator(); + + while (not _state and _nonLeafInstanceLocator.isValid()) { + Instance* nonLeaf = _nonLeafInstanceLocator.getElement(); + + if (not _topInstance or (nonLeaf == _topInstance)) { + Cell* masterCell = nonLeaf->getMasterCell(); + _occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); + if (_occurrenceLocator.isValid()) { + _state = 2; + break; + } + } + _nonLeafInstanceLocator.progress(); + } + } +} + + +Cell_LeafInstanceOccurrences::Locator::Locator ( const Locator& locator ) + : Inherit() + , _cell (locator._cell) + , _topInstance (locator._topInstance) + , _state (locator._state) + , _leafInstanceLocator (locator._leafInstanceLocator) + , _nonLeafInstanceLocator(locator._nonLeafInstanceLocator) + , _occurrenceLocator (locator._occurrenceLocator) +{ } + + +Cell_LeafInstanceOccurrences::Locator& Cell_LeafInstanceOccurrences::Locator::operator= ( const Locator& locator ) +{ + _cell = locator._cell; + _topInstance = locator._topInstance; + _state = locator._state; + _leafInstanceLocator = locator._leafInstanceLocator; + _nonLeafInstanceLocator = locator._nonLeafInstanceLocator; + _occurrenceLocator = locator._occurrenceLocator; + return *this; +} + + +Occurrence Cell_LeafInstanceOccurrences::Locator::getElement () const +{ + if (_state) { + switch (_state) { + case 1 : return Occurrence( _leafInstanceLocator.getElement() ); + case 2 : { + Occurrence occurrence = _occurrenceLocator.getElement(); + Entity* entity = occurrence.getEntity(); + Path path = Path( _nonLeafInstanceLocator.getElement(), occurrence.getPath() ); + return Occurrence( entity, path ); + } + } + } + return Occurrence(); +} + + +Locator* Cell_LeafInstanceOccurrences::Locator::getClone () const +{ return new Locator( *this ); } + + +bool Cell_LeafInstanceOccurrences::Locator::isValid () const +{ return (_state != 0); } + + +void Cell_LeafInstanceOccurrences::Locator::progress () +{ + if (_state) { + switch (_state) { + case 1 : + _leafInstanceLocator.progress(); + if (!_leafInstanceLocator.isValid()) { + _state = 0; + _nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator(); + while (!_state && _nonLeafInstanceLocator.isValid()) { + Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); + _occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); + if (_occurrenceLocator.isValid()) + _state = 2; + else + _nonLeafInstanceLocator.progress(); + } + } + break; + case 2 : + _occurrenceLocator.progress(); + if (not _occurrenceLocator.isValid()) { + _state = 0; + if (_nonLeafInstanceLocator.isValid()) { + _nonLeafInstanceLocator.progress(); + + while (not _state and _nonLeafInstanceLocator.isValid()) { + Instance* nonLeaf = _nonLeafInstanceLocator.getElement(); + + if (not _topInstance or (nonLeaf == _topInstance)) { Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); + _occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); - if (_occurrenceLocator.isValid()) - _state = 2; - else - _nonLeafInstanceLocator.progress(); - } - } - } -} - -Cell_LeafInstanceOccurrences::Locator::Locator(const Locator& locator) -// ********************************************************************** -: Inherit(), - _cell(locator._cell), - _state(locator._state), - _leafInstanceLocator(locator._leafInstanceLocator), - _nonLeafInstanceLocator(locator._nonLeafInstanceLocator), - _occurrenceLocator(locator._occurrenceLocator) -{ -} - -Cell_LeafInstanceOccurrences::Locator& Cell_LeafInstanceOccurrences::Locator::operator=(const Locator& locator) -// **************************************************************************************************** -{ - _cell = locator._cell; - _state = locator._state; - _leafInstanceLocator = locator._leafInstanceLocator; - _nonLeafInstanceLocator = locator._nonLeafInstanceLocator; - _occurrenceLocator = locator._occurrenceLocator; - return *this; -} - -Occurrence Cell_LeafInstanceOccurrences::Locator::getElement() const -// ******************************************************************* -{ - if (_state) { - switch (_state) { - case 1 : return Occurrence(_leafInstanceLocator.getElement()); - case 2 : { - Occurrence occurrence = _occurrenceLocator.getElement(); - Entity* entity = occurrence.getEntity(); - Path path = Path(_nonLeafInstanceLocator.getElement(), occurrence.getPath()); - return Occurrence(entity, path); - } - } - } - return Occurrence(); -} - -Locator* Cell_LeafInstanceOccurrences::Locator::getClone() const -// *************************************************************************** -{ - return new Locator(*this); -} - -bool Cell_LeafInstanceOccurrences::Locator::isValid() const -// *********************************************************** -{ - return (_state != 0); -} - -void Cell_LeafInstanceOccurrences::Locator::progress() -// ****************************************************** -{ - if (_state) { - switch (_state) { - case 1 : - _leafInstanceLocator.progress(); - if (!_leafInstanceLocator.isValid()) { - _state = 0; - _nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator(); - while (!_state && _nonLeafInstanceLocator.isValid()) { - Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); - _occurrenceLocator = masterCell->getLeafInstanceOccurrences().getLocator(); - if (_occurrenceLocator.isValid()) - _state = 2; - else - _nonLeafInstanceLocator.progress(); - } + if (_occurrenceLocator.isValid()) { + _state = 2; + break; } - break; - case 2 : - _occurrenceLocator.progress(); - if (!_occurrenceLocator.isValid()) { - _state = 0; - if (_nonLeafInstanceLocator.isValid()) { - _nonLeafInstanceLocator.progress(); - while (!_state && _nonLeafInstanceLocator.isValid()) { - Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); - _occurrenceLocator = - masterCell->getLeafInstanceOccurrences().getLocator(); - if (_occurrenceLocator.isValid()) - _state = 2; - else - _nonLeafInstanceLocator.progress(); - } - } - } - break; + } + + _nonLeafInstanceLocator.progress(); + } + } } + break; } + } } -string Cell_LeafInstanceOccurrences::Locator::_getString() const -// **************************************************************** +string Cell_LeafInstanceOccurrences::Locator::_getString () const { string s = "<" + _TName("Cell::LeafInstanceOccurrences::Locator"); - if (_cell) s += " " + getString(_cell); + if (_cell) s += " " + getString(_cell); + if (_topInstance) s += " " + getString(_topInstance); s += ">"; return s; } - // **************************************************************************************************** // Cell_LeafInstanceOccurrencesUnder implementation // **************************************************************************************************** @@ -3611,138 +3565,142 @@ string Cell_LeafInstanceOccurrencesUnder::Locator::_getString() const } +// ------------------------------------------------------------------- +// class : "Cell_NonLeafInstanceOccurrences". -// **************************************************************************************************** -// Cell_NonLeafInstanceOccurrences implementation -// **************************************************************************************************** +Cell_NonLeafInstanceOccurrences::Cell_NonLeafInstanceOccurrences ( const Cell* cell, const Instance* topInstance ) + : Inherit() + , _cell (cell) + , _topInstance(topInstance) +{ } -Cell_NonLeafInstanceOccurrences::Cell_NonLeafInstanceOccurrences(const Cell* cell) -// ******************************************************************************* -: Inherit(), - _cell(cell) + +Cell_NonLeafInstanceOccurrences::Cell_NonLeafInstanceOccurrences ( const Cell_NonLeafInstanceOccurrences& occurrences ) + : Inherit() + , _cell (occurrences._cell) + , _topInstance(occurrences._topInstance) +{ } + + +Cell_NonLeafInstanceOccurrences& Cell_NonLeafInstanceOccurrences::operator= ( const Cell_NonLeafInstanceOccurrences& occurrences ) { -} - -Cell_NonLeafInstanceOccurrences::Cell_NonLeafInstanceOccurrences(const Cell_NonLeafInstanceOccurrences& occurrences) -// **************************************************************************************************** -: Inherit(), - _cell(occurrences._cell) -{ -} - -Cell_NonLeafInstanceOccurrences& Cell_NonLeafInstanceOccurrences::operator=(const Cell_NonLeafInstanceOccurrences& occurrences) -// **************************************************************************************************** -{ - _cell = occurrences._cell; - return *this; -} - -Collection* Cell_NonLeafInstanceOccurrences::getClone() const -// ********************************************************************* -{ - return new Cell_NonLeafInstanceOccurrences(*this); -} - -Locator* Cell_NonLeafInstanceOccurrences::getLocator() const -// ******************************************************************** -{ - return new Locator(_cell); -} - -string Cell_NonLeafInstanceOccurrences::_getString() const -// ******************************************************* -{ - string s = "<" + _TName("Cell::NonLeafInstanceOccurrences"); - if (_cell) s += " " + getString(_cell); - s += ">"; - return s; + _cell = occurrences._cell; + _topInstance = occurrences._topInstance; + return *this; } +Collection* Cell_NonLeafInstanceOccurrences::getClone () const +{ return new Cell_NonLeafInstanceOccurrences(*this); } -// **************************************************************************************************** -// Cell_NonLeafInstanceOccurrences::Locator implementation -// **************************************************************************************************** -Cell_NonLeafInstanceOccurrences::Locator::Locator(const Cell* cell) -// **************************************************************** +Locator* Cell_NonLeafInstanceOccurrences::getLocator () const +{ return new Locator ( _cell, _topInstance ); } + + +string Cell_NonLeafInstanceOccurrences::_getString () const +{ + string s = "<" + _TName("Cell::NonLeafInstanceOccurrences"); + if (_cell) s += " " + getString(_cell); + if (_topInstance) s += " " + getString(_topInstance); + s += ">"; + return s; +} + + +// ------------------------------------------------------------------- +// class : "Cell_NonLeafInstanceOccurrences::Locator". + +Cell_NonLeafInstanceOccurrences::Locator::Locator ( const Cell* cell, const Instance* topInstance ) : Inherit () , _cell (cell) + , _topInstance (topInstance) , _state (0) , _nonLeafInstanceLocator() , _occurrenceLocator () { - if ( _cell ) { + if (_cell) { _nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator(); - if ( _nonLeafInstanceLocator.isValid() ) { - _state = 1; - } + _nonLeafProgress( true ); + if (_nonLeafInstanceLocator.isValid()) _state = 1; } } -Cell_NonLeafInstanceOccurrences::Locator::Locator(const Locator& locator) -// ********************************************************************** + +Cell_NonLeafInstanceOccurrences::Locator::Locator ( const Locator& locator ) : Inherit () , _cell (locator._cell) + , _topInstance (locator._topInstance) , _state (locator._state) , _nonLeafInstanceLocator(locator._nonLeafInstanceLocator) , _occurrenceLocator (locator._occurrenceLocator) { } -Cell_NonLeafInstanceOccurrences::Locator& Cell_NonLeafInstanceOccurrences::Locator::operator=(const Locator& locator) -// ******************************************************************************************************************** + +Cell_NonLeafInstanceOccurrences::Locator& Cell_NonLeafInstanceOccurrences::Locator::operator= ( const Locator& locator ) { _cell = locator._cell; + _topInstance = locator._topInstance; _state = locator._state; _nonLeafInstanceLocator = locator._nonLeafInstanceLocator; _occurrenceLocator = locator._occurrenceLocator; return *this; } -Occurrence Cell_NonLeafInstanceOccurrences::Locator::getElement() const -// ********************************************************************* +inline void Cell_NonLeafInstanceOccurrences::Locator::_nonLeafProgress ( bool inCTOR ) { - if ( _state ) { + if (not _nonLeafInstanceLocator.isValid()) return; + + if (not inCTOR) _nonLeafInstanceLocator.progress(); + if (not _topInstance) return; + + while ( _nonLeafInstanceLocator.isValid() ) { + Instance* nonLeaf = _nonLeafInstanceLocator.getElement(); + if (nonLeaf == _topInstance) break; + + _nonLeafInstanceLocator.progress(); + } +} + + +Occurrence Cell_NonLeafInstanceOccurrences::Locator::getElement () const +{ + if (_state) { switch ( _state ) { case 1 : return Occurrence(_nonLeafInstanceLocator.getElement()); - case 2 : - { + case 2 : { Occurrence occurrence = _occurrenceLocator.getElement(); Entity* entity = occurrence.getEntity(); Path path = Path(_nonLeafInstanceLocator.getElement(), occurrence.getPath()); return Occurrence(entity, path); - } + } } } return Occurrence(); } -Locator* Cell_NonLeafInstanceOccurrences::Locator::getClone() const -// ***************************************************************************** -{ - return new Locator(*this); -} -bool Cell_NonLeafInstanceOccurrences::Locator::isValid() const -// ************************************************************ -{ - return ( _state != 0 ); -} +Locator* Cell_NonLeafInstanceOccurrences::Locator::getClone () const +{ return new Locator( *this ); } -void Cell_NonLeafInstanceOccurrences::Locator::progress() -// ******************************************************* + +bool Cell_NonLeafInstanceOccurrences::Locator::isValid () const +{ return (_state != 0); } + + +void Cell_NonLeafInstanceOccurrences::Locator::progress () { if ( _state ) { switch ( _state ) { - case 1: - { - _nonLeafInstanceLocator.progress(); - if ( _nonLeafInstanceLocator.isValid() ) break; + case 1: { + _nonLeafProgress( false ); + if (_nonLeafInstanceLocator.isValid()) break; _state = 2; _nonLeafInstanceLocator = _cell->getNonLeafInstances().getLocator(); - if ( not _nonLeafInstanceLocator.isValid() ) { + _nonLeafProgress( true ); + if (not _nonLeafInstanceLocator.isValid()) { _state = 0; break; } @@ -3750,14 +3708,14 @@ void Cell_NonLeafInstanceOccurrences::Locator::progress() Cell* masterCell = _nonLeafInstanceLocator.getElement()->getMasterCell(); _occurrenceLocator = masterCell->getNonLeafInstanceOccurrences().getLocator(); - if ( _occurrenceLocator.isValid() ) break; - } + if (_occurrenceLocator.isValid()) break; + } case 2: - _occurrenceLocator.progress (); + _occurrenceLocator.progress(); - while ( (_state != 0) and not _occurrenceLocator.isValid() ) { - _nonLeafInstanceLocator.progress(); - if ( not _nonLeafInstanceLocator.isValid() ) { + while ( _state and not _occurrenceLocator.isValid() ) { + _nonLeafProgress( false ); + if (not _nonLeafInstanceLocator.isValid()) { _state = 0; break; } @@ -3769,15 +3727,15 @@ void Cell_NonLeafInstanceOccurrences::Locator::progress() } } -string Cell_NonLeafInstanceOccurrences::Locator::_getString() const -// **************************************************************** -{ - string s = "<" + _TName("Cell::NonLeafInstanceOccurrences::Locator"); - if (_cell) s += " " + getString(_cell); - s += ">"; - return s; -} +string Cell_NonLeafInstanceOccurrences::Locator::_getString () const +{ + string s = "<" + _TName("Cell::NonLeafInstanceOccurrences::Locator"); + if (_cell) s += " " + getString(_cell); + if (_topInstance) s += " " + getString(_topInstance); + s += ">"; + return s; +} // **************************************************************************************************** diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index b046dcaa..9ae8a517 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -462,9 +462,9 @@ class Cell : public Entity { public: Occurrences getOccurrencesUnder(const Box& area, unsigned searchDepth = std::numeric_limits::max()) const; public: Occurrences getTerminalInstanceOccurrences() const; public: Occurrences getTerminalInstanceOccurrencesUnder(const Box& area) const; - public: Occurrences getLeafInstanceOccurrences() const; + public: Occurrences getLeafInstanceOccurrences( const Instance* topInstance=NULL ) const; public: Occurrences getLeafInstanceOccurrencesUnder(const Box& area) const; - public: Occurrences getNonLeafInstanceOccurrences() const; + public: Occurrences getNonLeafInstanceOccurrences( const Instance* topInstance=NULL ) const; public: Occurrences getComponentOccurrences(const Layer::Mask& mask = ~0) const; public: Occurrences getComponentOccurrencesUnder(const Box& area, const Layer::Mask& mask = ~0) const; public: Occurrences getHyperNetRootNetOccurrences() const; diff --git a/hurricane/src/hurricane/hurricane/DeepNet.h b/hurricane/src/hurricane/hurricane/DeepNet.h index 20bb85f1..0afd4045 100644 --- a/hurricane/src/hurricane/hurricane/DeepNet.h +++ b/hurricane/src/hurricane/hurricane/DeepNet.h @@ -82,4 +82,6 @@ namespace Hurricane { } // Hurricane namespace. +INSPECTOR_P_SUPPORT(Hurricane::DeepNet); + #endif diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index 3795cd4c..87393edc 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -38,6 +38,7 @@ #include "hurricane/RoutingPad.h" #include "hurricane/viewer/Script.h" #include "crlcore/Measures.h" +#include "crlcore/AllianceFramework.h" #include "anabatic/AutoContact.h" #include "katana/Block.h" #include "katana/DataNegociate.h" @@ -148,7 +149,9 @@ namespace Katana { using Hurricane::NetRoutingState; using Hurricane::NetRoutingExtension; using Hurricane::Cell; + using Hurricane::Instance; using CRL::System; + using CRL::AllianceFramework; using CRL::addMeasure; using CRL::Measures; using CRL::MeasuresSet; @@ -311,6 +314,18 @@ namespace Katana { KatanaEngine* KatanaEngine::create ( Cell* cell ) { + AllianceFramework* af = AllianceFramework::get(); + for ( Instance* instance : cell->getInstances() ) { + if (af->isPad(instance->getMasterCell())) { + throw Error( "KatanaEngine::create(): Must not be run at chip level, but a corona level.\n" + " Guessing \"%s\" is a chip because instance \"%s\" is a pad (\"%s\")." + , getString(cell->getName()).c_str() + , getString(instance->getName()).c_str() + , getString(instance->getMasterCell()->getName()).c_str() + ); + } + } + KatanaEngine* katana = new KatanaEngine ( cell ); katana->_postCreate(); diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index 7c3fea1d..a1e7b348 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -824,7 +824,7 @@ namespace { _planes.insert( make_pair(regular->getBasicLayer(),new Plane(regular,rp)) ); - if (lg->getType() == Constant::PinOnly) continue; + //if (lg->getType() == Constant::PinOnly) continue; const BasicLayer* blockageLayer = regular->getBasicLayer()->getBlockageLayer(); if (not blockageLayer) continue; @@ -1182,7 +1182,7 @@ namespace Katana { QueryPowerRails query ( this ); Technology* technology = DataBase::getDB()->getTechnology(); - for( BasicLayer* layer : technology->getBasicLayers() ) { + for ( BasicLayer* layer : technology->getBasicLayers() ) { if ( (layer->getMaterial() != BasicLayer::Material::metal) and (layer->getMaterial() != BasicLayer::Material::blockage) ) continue;