From ae6eeb8f56c28f472f573203ef744486ef3c65fc Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 26 Jun 2015 18:35:11 +0200 Subject: [PATCH] Merged QuadTrees in overlayed Cells (placed together). * New: In Hurricane, in Cell & Instance, add the ability to merge the QuadTree when *second level* instances of a Cell are placed in the same space as the top Cell. This is the case of a deeply hierarchical design made of only standard cells that are to be placed in a "flat" manner. The design is uniquified then the intermediate instances models, which should be unique at that point have their QuadTree merged through a call to Instance::slaveAbutmentBox(). That method will make the model of the instance use the QuadTree of the Cell to which the instance belong. The instance model no longer posseses a dedicated QuadTree. As a corollary the abutment box of both Cell are kept identical and the Instance has it's transformation set to (0,0,ID). Remark: when we talk about "QuadTree", we mean in fact the QuadTree for the instances *and* the SliceMap (Layer+QuadTree). Consequence in Query: when going through the resulting "flattened" QuadTree we will find objects with an incomplete Path du to the fact that we didn't have to explore their Instance/Cell level to reach them. The shunted part of the Path is stored in the Go master Cell in the _shuntedPath attribute. This also affect the displayed depth of hierarchy, but not too badly. * New: In Hurricane, in Cell, new methods: - Cell::updatePlacedFlag() : set the placement flags. - Cell::isUnique() : one or less instance. - Cell::isUniquified() : is the result of an uniquification. - Cell::isUniquifyMaster() : is the reference cell of the uniquification. * Change: In Hurricane, in Cell::Uniquify(), uniquify a Cell only if it is unplaced. We do not need to duplicate placed Cells (see datapathes). --- crlcore/src/ccore/alliance/ap/ApParser.cpp | 10 +- cumulus/src/plugins/RSavePlugin.py | 8 +- etesian/src/EtesianEngine.cpp | 11 +- hurricane/doc/hurricane/Cell.dox | 12 + hurricane/doc/hurricane/Instance.dox | 10 + hurricane/src/hurricane/Cell.cpp | 236 +++++++++++++++---- hurricane/src/hurricane/CellCollections.cpp | 10 +- hurricane/src/hurricane/DeepNet.cpp | 1 - hurricane/src/hurricane/Instance.cpp | 178 +++++--------- hurricane/src/hurricane/SharedPath.cpp | 8 +- hurricane/src/hurricane/Slice.cpp | 4 +- hurricane/src/hurricane/UpdateSession.cpp | 10 +- hurricane/src/hurricane/hurricane/Cell.h | 28 ++- hurricane/src/hurricane/hurricane/Instance.h | 4 + hurricane/src/hurricane/hurricane/Query.h | 2 +- hurricane/src/isobar/PyCell.cpp | 10 +- hurricane/src/isobar/PyInstance.cpp | 14 ++ 17 files changed, 347 insertions(+), 209 deletions(-) diff --git a/crlcore/src/ccore/alliance/ap/ApParser.cpp b/crlcore/src/ccore/alliance/ap/ApParser.cpp index ef6f2ffb..9d3507e4 100644 --- a/crlcore/src/ccore/alliance/ap/ApParser.cpp +++ b/crlcore/src/ccore/alliance/ap/ApParser.cpp @@ -838,15 +838,7 @@ namespace { UpdateSession::close (); if (materializationState) Go::disableAutoMaterialization (); - - bool isPlaced = true; - forEach ( Instance*, iinstance, _cell->getInstances() ) { - if (iinstance->getPlacementStatus() == Instance::PlacementStatus::UNPLACED) { - isPlaced = false; - break; - } - } - if (isPlaced) _cell->setFlags( Cell::Flags::Placed ); + _cell->updatePlacedFlag(); fileStream.close (); } diff --git a/cumulus/src/plugins/RSavePlugin.py b/cumulus/src/plugins/RSavePlugin.py index 8d9afbff..292edadb 100644 --- a/cumulus/src/plugins/RSavePlugin.py +++ b/cumulus/src/plugins/RSavePlugin.py @@ -46,6 +46,10 @@ except Exception, e: # Write back layout to disk if everything has gone fine. # Must write all the sub-blocks of the core but *not* the # standard cell (mainly the feed-through). +# +# If the model has been uniquified, in the case of a merging +# of abutment box for placement, the netlist view must also +# be saved. def rsave ( cell, depth=0 ): if cell.isTerminal(): return @@ -54,7 +58,9 @@ def rsave ( cell, depth=0 ): if depth == 0: print ' o Recursive Save-Cell.' print ' %s+ %s (layout).' % ( ' '*(depth*2), cell.getName() ) - framework.saveCell( cell, CRL.Catalog.State.Physical ) + views = CRL.Catalog.State.Physical + if cell.isUniquified(): views |= CRL.Catalog.State.Logical + framework.saveCell( cell, views ) for instance in cell.getInstances(): masterCell = instance.getMasterCell() diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index 7827956f..39610890 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -472,11 +472,14 @@ namespace Etesian { Instance* instance = static_cast(occurrence.getEntity()); Cell* masterCell = instance->getMasterCell(); - if (masterCell->getAbutmentBox().isEmpty()) { + if ( masterCell->getAbutmentBox().isEmpty() + or ( (masterCell->getAbutmentBox().getHeight() == topAb.getHeight()) + and (masterCell->getAbutmentBox().getWidth () == topAb.getWidth ()) ) ) { // Have to check here if the model is fully placed or not. - masterCell->setAbutmentBox( topAb ); - instance->setTransformation( Transformation() ); // (0,0,ID). - instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); + //masterCell->setAbutmentBox( topAb ); + //instance->setTransformation( Transformation() ); // (0,0,ID). + //instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); + instance->slaveAbutmentBox(); } } UpdateSession::close(); diff --git a/hurricane/doc/hurricane/Cell.dox b/hurricane/doc/hurricane/Cell.dox index f3e7c84b..e9ca8e26 100644 --- a/hurricane/doc/hurricane/Cell.dox +++ b/hurricane/doc/hurricane/Cell.dox @@ -164,6 +164,18 @@ * \false. */ + //! \function bool Cell::isUnique () const; + //! Returns \true if the Cell has one or less instances, regardless of + //! it's uniquification state. + + //! \function bool Cell::isUniquified () const; + //! Returns \true if this Cell is the result of an uniquification \b and + //! is not the reference (the original) Cell. + + //! \function bool Cell::isUniquifyMaster () const; + //! Returns \true if the Cell has been uniquified and this is the original + //! Cell. The original Cell can have both normal instances and uniquified + //! instances. /*! \function void Cell::setName ( const Name& name ); * Allows to change the Cell Name. diff --git a/hurricane/doc/hurricane/Instance.dox b/hurricane/doc/hurricane/Instance.dox index 5d8e7899..7a6d9b8b 100644 --- a/hurricane/doc/hurricane/Instance.dox +++ b/hurricane/doc/hurricane/Instance.dox @@ -39,6 +39,16 @@ * \section secInstancePredefinedFilters Predefined filters * * Hurricane::Instance::getIsUnderFilter + * + * + * \section secInstanceDestroy Instance Destruction + * + * When the Instance::destroy() method is called, if the master Cell + * is uniquified, that is, is unique \b and a copy of the reference + * Cell, it is destroyed as well. That state means that the master + * Cell has been created for the only purpose as to serve as a model + * for this peculiar Instance. It is then logical that it should be + * removed with it. */ diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 225c4538..81bb29b4 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -19,6 +19,7 @@ //#define TEST_INTRUSIVESET +#include "hurricane/Warning.h" #include "hurricane/SharedName.h" #include "hurricane/Cell.h" #include "hurricane/DataBase.h" @@ -155,11 +156,12 @@ Cell::Cell(Library* library, const Name& name) : Inherit(), _library(library), _name(name), + _shuntedPath(), _instanceMap(), - _quadTree(), + _quadTree(new QuadTree()), _slaveInstanceSet(), _netMap(), - _sliceMap(), + _sliceMap(new SliceMap()), _extensionSlices(), _markerSet(), //_viewSet(), @@ -197,7 +199,7 @@ Box Cell::getBoundingBox() const if (_boundingBox.isEmpty()) { Box& boundingBox = (Box&)_boundingBox; boundingBox = _abutmentBox; - boundingBox.merge(_quadTree.getBoundingBox()); + boundingBox.merge(_quadTree->getBoundingBox()); for_each_slice(slice, getSlices()) { boundingBox.merge(slice->getBoundingBox()); end_for; @@ -232,6 +234,26 @@ bool Cell::isNetAlias ( const Name& name ) const return _netAliasSet.find(&key) != _netAliasSet.end(); } +bool Cell::isUnique() const +// ************************ +{ + return getSlaveInstances().getSize() < 2; +} + +bool Cell::isUniquified() const +// **************************** +{ + UniquifyRelation* relation = UniquifyRelation::get( this ); + return relation and (relation->getMasterOwner() != this); +} + +bool Cell::isUniquifyMaster() const +// ******************************** +{ + UniquifyRelation* relation = UniquifyRelation::get( this ); + return (not relation) or (relation->getMasterOwner() == this); +} + Net* Cell::getNet ( const Name& name ) const //****************************************** { @@ -266,13 +288,19 @@ void Cell::setName(const Name& name) void Cell::setAbutmentBox(const Box& abutmentBox) // ********************************************** { - if (abutmentBox != _abutmentBox) { - if (!_abutmentBox.isEmpty() && - (abutmentBox.isEmpty() || !abutmentBox.contains(_abutmentBox))) - _unfit(_abutmentBox); - _abutmentBox = abutmentBox; - _fit(_abutmentBox); - } + if (abutmentBox != _abutmentBox) { + if (not _abutmentBox.isEmpty() and + (abutmentBox.isEmpty() or not abutmentBox.contains(_abutmentBox))) + _unfit( _abutmentBox ); + _abutmentBox = abutmentBox; + _fit( _abutmentBox ); + } + + for ( Instance* instance : getInstances() ) { + Cell* masterCell = instance->getMasterCell(); + if (masterCell->getFlags().isset(Flags::MergedQuadTree)) + masterCell->setAbutmentBox( abutmentBox ); + } } @@ -424,6 +452,21 @@ Cell* Cell::getCloneMaster() const } +bool Cell::updatePlacedFlag() +// ************************** +{ + bool isPlaced = true; + for ( Instance* instance : getInstances() ) { + if (instance->getPlacementStatus() == Instance::PlacementStatus::UNPLACED) { + isPlaced = false; + break; + } + } + if (isPlaced) setFlags( Cell::Flags::Placed ); + return isPlaced; +} + + Cell* Cell::getClone() // ******************* { @@ -462,50 +505,146 @@ Cell* Cell::getClone() void Cell::uniquify(unsigned int depth) // ************************************ { +//cerr << "Cell::uniquify() " << this << endl; + vector toUniquify; set masterCells; - for ( Instance* iinstance : getInstances() ) { - Cell* masterCell = iinstance->getMasterCell(); + for ( Instance* instance : getInstances() ) { + Cell* masterCell = instance->getMasterCell(); if (masterCell->isTerminal()) continue; - masterCells.insert( masterCell ); - if (masterCell->getSlaveInstances().getSize() > 1) { - toUniquify.push_back( iinstance ); + if (masterCells.find(masterCell) == masterCells.end()) { + masterCells.insert( masterCell ); + masterCell->updatePlacedFlag(); + } + + if ( (masterCell->getSlaveInstances().getSize() > 1) and not masterCell->isPlaced() ) { + toUniquify.push_back( instance ); } } - for ( auto iinst : toUniquify ) { - iinst->uniquify(); - masterCells.insert( iinst->getMasterCell() ); + for ( auto instance : toUniquify ) { + instance->uniquify(); + masterCells.insert( instance->getMasterCell() ); } if (depth > 0) { - for ( auto icell : masterCells ) - icell->uniquify( depth-1 ); + for ( auto cell : masterCells ) + cell->uniquify( depth-1 ); } } void Cell::materialize() // ********************* { - forEach ( Instance*, iinstance, getInstances() ) { - if ( iinstance->getPlacementStatus() != Instance::PlacementStatus::UNPLACED ) - iinstance->materialize(); + if (_flags.isset(Flags::Materialized)) return; + + _flags |= Flags::Materialized; + + for ( Instance* instance : getInstances() ) { + if ( instance->getPlacementStatus() != Instance::PlacementStatus::UNPLACED ) + instance->materialize(); } - forEach ( Net* , inet , getNets () ) inet ->materialize(); - forEach ( Marker*, imarker, getMarkers() ) imarker->materialize(); + for ( Net* net : getNets () ) net ->materialize(); + for ( Marker* marker : getMarkers() ) marker->materialize(); } void Cell::unmaterialize() // *********************** { - for_each_instance(instance, getInstances()) instance->unmaterialize(); end_for; - for_each_net(net, getNets()) net->unmaterialize(); end_for; - for_each_marker(marker, getMarkers()) marker->unmaterialize(); end_for; + if (not _flags.isset(Flags::Materialized)) return; + + _flags &= ~Flags::Materialized; + + for ( Instance* instance : getInstances()) instance->unmaterialize(); + for ( Net* net : getNets() ) net ->unmaterialize(); + for ( Marker* marker : getMarkers() ) marker ->unmaterialize(); } +void Cell::slaveAbutmentBox ( Cell* topCell ) +// ****************************************** +{ + if (_flags.isset(Flags::MergedQuadTree)) { + cerr << Error( "Cell::slaveAbutmentBox(): %s is already slaved, action cancelled." + , getString(this).c_str() ) << endl; + return; + } + + if (not isUnique()) { + cerr << Error( "Cell::slaveAbutmentBox(): %s is *not* unique, action cancelled." + , getString(this).c_str() ) << endl; + return; + } + + _slaveAbutmentBox( topCell ); +} + +void Cell::_slaveAbutmentBox ( Cell* topCell ) +// ******************************************* +{ + if (not getAbutmentBox().isEmpty()) { + if ( (getAbutmentBox().getWidth() != topCell->getAbutmentBox().getWidth()) + or (getAbutmentBox().getWidth() != topCell->getAbutmentBox().getWidth()) ) { + cerr << Warning( "Slaving abutment boxes of different sizes, fixed blocks may shift.\n" + " topCell: %s (AB:%s)\n" + " slave : %s (AB:%s)" + , getString(topCell->getName()).c_str() + , getString(topCell->getAbutmentBox()).c_str() + , getString(getName()).c_str() + , getString(getAbutmentBox()).c_str() + ); + } + + Transformation transf ( topCell->getAbutmentBox().getXMin() - getAbutmentBox().getXMin() + , topCell->getAbutmentBox().getYMin() - getAbutmentBox().getYMin() ); + + for ( Instance* instance : getInstances() ) { + if (instance->getPlacementStatus() != Instance::PlacementStatus::UNPLACED) { + Transformation instanceTransf = instance->getTransformation(); + transf.applyOn( instanceTransf ); + instance->setTransformation( instanceTransf ); + } + } + } + + setAbutmentBox( topCell->getAbutmentBox() ); + + _changeQuadTree( topCell ); + + for ( Instance* instance : getInstances() ) { + Cell* masterCell = instance->getMasterCell(); + if (masterCell->getFlags().isset(Flags::MergedQuadTree)) + masterCell->_slaveAbutmentBox( topCell ); + } +} + + +void Cell::_changeQuadTree ( Cell* topCell ) +// ***************************************** +{ + bool isMaterialized = _flags.isset(Flags::Materialized); + + unmaterialize(); + + if (topCell or _flags.isset(Flags::MergedQuadTree)) { + delete _sliceMap; + delete _quadTree; + + if (topCell) { + _sliceMap = topCell->_getSliceMap(); + _quadTree = topCell->_getQuadTree(); + } else { + _sliceMap = new SliceMap(); + _quadTree = new QuadTree(); + } + } + + if (isMaterialized) materialize(); +} + + void Cell::_postCreate() // ********************* { @@ -517,25 +656,30 @@ void Cell::_postCreate() void Cell::_preDestroy() // ******************** { - while(_slaveEntityMap.size()) { - _slaveEntityMap.begin()->second->destroy(); - } + while ( _slaveEntityMap.size() ) { + _slaveEntityMap.begin()->second->destroy(); + } - //for_each_view(view, getViews()) view->SetCell(NULL); end_for; - for_each_marker(marker, getMarkers()) marker->destroy(); end_for; - for_each_instance(slaveInstance, getSlaveInstances()) slaveInstance->destroy(); end_for; - for_each_instance(instance, getInstances()) instance->destroy(); end_for; - forEach( Net*, inet, getNets() ) { - inet->_getMainName().detachAll(); - inet->destroy(); - } - for ( auto islave : _netAliasSet ) delete islave; - for_each_slice(slice, getSlices()) slice->_destroy(); end_for; - while(!_extensionSlices.empty()) _removeSlice(_extensionSlices.begin()->second); +//for ( View* view : getViews() ) view->setCell( NULL ); + for ( Marker* marker : getMarkers() ) marker->destroy(); + for ( Instance* slaveInstance : getSlaveInstances() ) slaveInstance->destroy(); + for ( Instance* instance : getInstances() ) instance->destroy(); + for ( Net* net : getNets() ) { + net->_getMainName().detachAll(); + net->destroy(); + } + for ( auto islave : _netAliasSet ) delete islave; + for ( Slice* slice : getSlices() ) slice->_destroy(); + while ( not _extensionSlices.empty() ) _removeSlice( _extensionSlices.begin()->second ); - _library->_getCellMap()._remove(this); + if (not _flags.isset(Flags::MergedQuadTree)) { + delete _sliceMap; + delete _quadTree; + } + + _library->_getCellMap()._remove( this ); - Inherit::_preDestroy(); + Inherit::_preDestroy(); } string Cell::_getString() const @@ -554,12 +698,12 @@ Record* Cell::_getRecord() const record->add( getSlot("_library" , _library ) ); record->add( getSlot("_name" , &_name ) ); record->add( getSlot("_instances" , &_instanceMap ) ); - record->add( getSlot("_quadTree" , &_quadTree ) ); + record->add( getSlot("_quadTree" , _quadTree ) ); record->add( getSlot("_slaveInstances", &_slaveInstanceSet) ); record->add( getSlot("_netMap" , &_netMap ) ); record->add( getSlot("_netAliasSet" , &_netAliasSet ) ); record->add( getSlot("_pinMap" , &_pinMap ) ); - record->add( getSlot("_sliceMap" , &_sliceMap ) ); + record->add( getSlot("_sliceMap" , _sliceMap ) ); record->add( getSlot("_markerSet" , &_markerSet ) ); record->add( getSlot("_slaveEntityMap", &_slaveEntityMap ) ); record->add( getSlot("_abutmentBox" , &_abutmentBox ) ); diff --git a/hurricane/src/hurricane/CellCollections.cpp b/hurricane/src/hurricane/CellCollections.cpp index 693e5b4c..5f05d09b 100644 --- a/hurricane/src/hurricane/CellCollections.cpp +++ b/hurricane/src/hurricane/CellCollections.cpp @@ -1775,7 +1775,7 @@ Instances Cell::getInstancesUnder(const Box& area) const // ***************************************************** { // return _quadTree.getGosUnder(area).getSubSet(); - return SubTypeCollection(_quadTree.getGosUnder(area)); + return SubTypeCollection(_quadTree->getGosUnder(area)); } Instances Cell::getSlaveInstances() const @@ -1951,21 +1951,21 @@ Rubbers Cell::getRubbers() const // ***************************** { // return _quadTree.getGos().getSubSet(); - return SubTypeCollection(_quadTree.getGos()); + return SubTypeCollection(_quadTree->getGos()); } Rubbers Cell::getRubbersUnder(const Box& area) const // ************************************************* { // return (area.isEmpty()) ? Rubbers() : _quadTree.getGosUnder(area).getSubSet(); - return SubTypeCollection(_quadTree.getGosUnder(area)); + return SubTypeCollection(_quadTree->getGosUnder(area)); } Markers Cell::getMarkersUnder(const Box& area) const // ************************************************* { // return (area.isEmpty()) ? Markers() : _quadTree.getGosUnder(area).getSubSet(); - return SubTypeCollection(_quadTree.getGosUnder(area)); + return SubTypeCollection(_quadTree->getGosUnder(area)); } References Cell::getReferences() const @@ -2171,7 +2171,7 @@ Cell_Slices::Locator::Locator(const Cell* cell, const Layer::Mask& mask) _sliceLocator() { if (_cell && !_mask.zero()) { - _sliceLocator = ((Cell*)_cell)->_getSliceMap().getElements().getLocator(); + _sliceLocator = ((Cell*)_cell)->_getSliceMap()->getElements().getLocator(); while (_sliceLocator.isValid() && !(_sliceLocator.getElement()->getLayer()->getMask() & _mask)) _sliceLocator.progress(); } diff --git a/hurricane/src/hurricane/DeepNet.cpp b/hurricane/src/hurricane/DeepNet.cpp index fab040f0..00794bd0 100644 --- a/hurricane/src/hurricane/DeepNet.cpp +++ b/hurricane/src/hurricane/DeepNet.cpp @@ -81,7 +81,6 @@ namespace Hurricane { { size_t nbRoutingPads = 0; HyperNet hyperNet ( _netOccurrence ); - RoutingPad* previousRp = NULL; RoutingPad* currentRp = NULL; forEach ( Occurrence, ioccurrence, hyperNet.getLeafPlugOccurrences() ) { diff --git a/hurricane/src/hurricane/Instance.cpp b/hurricane/src/hurricane/Instance.cpp index 06a67c12..ae5dbb9e 100644 --- a/hurricane/src/hurricane/Instance.cpp +++ b/hurricane/src/hurricane/Instance.cpp @@ -200,23 +200,33 @@ Instance::Instance(Cell* cell, const Name& name, Cell* masterCell, const Transfo Instance* Instance::create(Cell* cell, const Name& name, Cell* masterCell, bool secureFlag) // **************************************************************************************** { - Instance* instance = - new Instance(cell, name, masterCell, Transformation(), PlacementStatus(), secureFlag); + if (not cell) + throw Error( "Instance::create(): NULL master Cell argument." ); - instance->_postCreate(); + // if (cell->isUniquified()) + // throw Error( "Instance::create(): %s master Cell is an uniquified copy.", getString(cell).c_str() ); - return instance; + Instance* instance = + new Instance(cell, name, masterCell, Transformation(), PlacementStatus(), secureFlag); + + instance->_postCreate(); + return instance; } Instance* Instance::create(Cell* cell, const Name& name, Cell* masterCell, const Transformation& transformation, const PlacementStatus& placementstatus, bool secureFlag) -// **************************************************************************************************** +// ********************************************************************************************************************************************************************** { - Instance* instance = - new Instance(cell, name, masterCell, transformation, placementstatus, secureFlag); + if (not cell) + throw Error( "Instance::create(): NULL master Cell argument." ); - instance->_postCreate(); + // if (cell->isUniquified()) + // throw Error( "Instance::create(): %s master Cell is an uniquified copy.", getString(cell).c_str() ); - return instance; + Instance* instance = + new Instance(cell, name, masterCell, transformation, placementstatus, secureFlag); + + instance->_postCreate(); + return instance; } Box Instance::getBoundingBox() const @@ -261,6 +271,25 @@ bool Instance::isLeaf() const return getMasterCell()->isLeaf(); } +bool Instance::isUnique() const +// **************************** +{ + return _masterCell->isUnique(); +} + +bool Instance::isUniquified() const +// ******************************** +{ + return _masterCell->isUniquified(); +} + +bool Instance::isUniquifyMaster() const +// ************************************ +{ + return _masterCell->isUniquifyMaster(); +} + + InstanceFilter Instance::getIsUnderFilter(const Box& area) // ******************************************************* { @@ -453,15 +482,26 @@ void Instance::setMasterCell(Cell* masterCell, bool secureFlag) void Instance::uniquify() // ********************** { - if (_masterCell->getSlaveInstances().getSize() == 1) { - cerr << Warning( "Instance::uniquify(): Master Cell %s of %s is already unique." + if (_masterCell->isUniquified()) { + cerr << Warning( "Instance::uniquify(): Master Cell %s of %s is already uniquified, cancelled." , getString(_masterCell->getName()).c_str() , getString(getName()).c_str() ) << endl; + return; } setMasterCell( _masterCell->getClone() ); } +void Instance::slaveAbutmentBox() +// ****************************** +{ + if (not _masterCell->isUniquified()) uniquify(); + setTransformation( Transformation() ); + setPlacementStatus( Instance::PlacementStatus::PLACED ); + _masterCell->slaveAbutmentBox( getCell() ); + _masterCell->_setShuntedPath( Path(getCell()->getShuntedPath(),this) ); +} + Instance* Instance::getClone(Cell* cloneCell) const // ************************************************ { @@ -524,6 +564,8 @@ void Instance::_preDestroy() _masterCell->_getSlaveInstanceSet()._remove(this); _cell->_getInstanceMap()._remove(this); + + if (_masterCell->isUniquified()) _masterCell->destroy(); } string Instance::_getString() const @@ -553,120 +595,6 @@ Record* Instance::_getRecord() const return record; } -//void Instance::_DrawPhantoms(View* view, const Box& updateArea, const Transformation& transformation) -//// ************************************************************************************************** -//{ -// Symbol* symbol = _masterCell->getSymbol(); -// if (!symbol) { -// Box masterArea = updateArea; -// Transformation masterTransformation = _transformation; -// _transformation.getInvert().ApplyOn(masterArea); -// transformation.ApplyOn(masterTransformation); -// _masterCell->_DrawPhantoms(view, masterArea, masterTransformation); -// } -//} -// -//void Instance::_DrawBoundaries(View* view, const Box& updateArea, const Transformation& transformation) -//// **************************************************************************************************** -//{ -// Box masterArea = updateArea; -// Transformation masterTransformation = _transformation; -// _transformation.getInvert().ApplyOn(masterArea); -// transformation.ApplyOn(masterTransformation); -// Symbol* symbol = _masterCell->getSymbol(); -// if (!symbol) -// _masterCell->_DrawBoundaries(view, masterArea, masterTransformation); -// else -// _masterCell->getSymbol()->_Draw(view, masterArea, masterTransformation); -//} -// -//void Instance::_DrawRubbers(View* view, const Box& updateArea, const Transformation& transformation) -//// ************************************************************************************************* -//{ -// Box masterArea = updateArea; -// Transformation masterTransformation = _transformation; -// _transformation.getInvert().ApplyOn(masterArea); -// transformation.ApplyOn(masterTransformation); -// _masterCell->_DrawRubbers(view, masterArea, masterTransformation); -//} -// -//void Instance::_DrawMarkers(View* view, const Box& updateArea, const Transformation& transformation) -//// ************************************************************************************************* -//{ -// Box masterArea = updateArea; -// Transformation masterTransformation = _transformation; -// _transformation.getInvert().ApplyOn(masterArea); -// transformation.ApplyOn(masterTransformation); -// _masterCell->_DrawMarkers(view, masterArea, masterTransformation); -//} -// -//void Instance::_DrawDisplaySlots(View* view, const Box& area, const Box& updateArea, const Transformation& transformation) -//// *********************************************************************************************************************** -//{ -// Box masterArea = updateArea; -// Transformation masterTransformation = _transformation; -// _transformation.getInvert().ApplyOn(masterArea); -// transformation.ApplyOn(masterTransformation); -// _masterCell->_DrawDisplaySlots(view, area, masterArea, masterTransformation); -//} -// -//bool Instance::_IsInterceptedBy(View* view, const Point& point, const DbU::Unit& aperture) const -//// **************************************************************************************** -//{ -// Symbol* symbol = _masterCell->getSymbol(); -// if (!symbol) -// return (view->PhantomsAreVisible() || view->BoundariesAreVisible()) && -// getAbutmentBox().intersect(Box(point).Inflate(aperture)); -// else { -// Point masterPoint = point; -// _transformation.getInvert().ApplyOn(masterPoint); -// return (view->BoundariesAreVisible() && symbol->_IsInterceptedBy(view, masterPoint, aperture)); -// } -//} -// -//void Instance::_Draw(View* view, BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation) -//// **************************************************************************************************** -//{ -// Symbol* symbol = _masterCell->getSymbol(); -// if (!symbol) { -// Box masterArea = updateArea; -// Transformation masterTransformation = _transformation; -// _transformation.getInvert().ApplyOn(masterArea); -// transformation.ApplyOn(masterTransformation); -// _masterCell->_DrawContent(view, basicLayer, masterArea, masterTransformation); -// } -//} -// -//void Instance::_Highlight(View* view, const Box& updateArea, const Transformation& transformation) -//// *********************************************************************************************** -//{ -// Symbol* symbol = _masterCell->getSymbol(); -// if (!symbol) { -// Box abutmentBox = transformation.getBox(getAbutmentBox()); -// view->FillRectangle(abutmentBox); -// view->DrawRectangle(abutmentBox); -// -// if ( view->getScale() > 1 ) -// { -// if ( view->IsTextVisible() ) -// { -// string text = getString ( _name ) + " (" -// + getString ( getValue ( abutmentBox.getXCenter () ) ) + "," -// + getString ( getValue ( abutmentBox.getYCenter () ) ) + ")"; -// view->DrawString ( text, abutmentBox.getXMin(), abutmentBox.getYMax() ); -// } -// } -// } -// else { -// Box masterArea = updateArea; -// Transformation masterTransformation = _transformation; -// _transformation.getInvert().ApplyOn(masterArea); -// transformation.ApplyOn(masterTransformation); -// symbol->_Highlight(view, masterArea, masterTransformation); -// } -//} -// - // **************************************************************************************************** // Instance::PlugMap implementation // **************************************************************************************************** diff --git a/hurricane/src/hurricane/SharedPath.cpp b/hurricane/src/hurricane/SharedPath.cpp index d84763ef..04d83f7e 100644 --- a/hurricane/src/hurricane/SharedPath.cpp +++ b/hurricane/src/hurricane/SharedPath.cpp @@ -121,7 +121,13 @@ SharedPath::SharedPath(Instance* headInstance, SharedPath* tailSharedPath) throw Error("Can't create " + _TName("SharedPath") + " : already exists"); if (_tailSharedPath && (_tailSharedPath->getOwnerCell() != _headInstance->getMasterCell())) - throw Error("Can't create " + _TName("SharedPath") + " : incompatible tail path"); + throw Error( "Can't create %s, incompatible tail path between:\n" + " - head owner %s\n" + " - tail owner %s\n" + , _TName("SharedPath").c_str() + , getString(_headInstance ->getMasterCell()).c_str() + , getString(_tailSharedPath->getOwnerCell ()).c_str() + ); _headInstance->_getSharedPathMap()._insert(this); } diff --git a/hurricane/src/hurricane/Slice.cpp b/hurricane/src/hurricane/Slice.cpp index 01de60a9..17751fb8 100644 --- a/hurricane/src/hurricane/Slice.cpp +++ b/hurricane/src/hurricane/Slice.cpp @@ -48,13 +48,13 @@ Slice::Slice(Cell* cell, const Layer* layer) if (_cell->getSlice(_layer)) throw Error("Can't create " + _TName("Slice") + " : already exists"); - _cell->_getSliceMap()._insert(this); + _cell->_getSliceMap()->_insert(this); } Slice::~Slice() // ************ { - _cell->_getSliceMap()._remove(this); + _cell->_getSliceMap()->_remove(this); } Components Slice::getComponents() const diff --git a/hurricane/src/hurricane/UpdateSession.cpp b/hurricane/src/hurricane/UpdateSession.cpp index 60f481cf..0a6e31e2 100644 --- a/hurricane/src/hurricane/UpdateSession.cpp +++ b/hurricane/src/hurricane/UpdateSession.cpp @@ -90,13 +90,13 @@ void UpdateSession::_destroy() UPDATOR_STACK->pop(); vector changedCells; - forEach( DBo*, iowner, getOwners() ) { - Cell* cell = dynamic_cast(*iowner); + for ( DBo* owner : getOwners() ) { + Cell* cell = dynamic_cast(owner); if (cell) { //cerr << "Notify Cell::CellChanged to: " << cell << endl; changedCells.push_back( cell ); } else { - Go* go = dynamic_cast(*iowner); + Go* go = dynamic_cast(owner); if (go) go->materialize(); } } @@ -180,8 +180,8 @@ void UpdateSession::onNotOwned() //cerr << "Notify Cell::CellAboutToChange to: " << getCell() << endl; getCell()->put ( UPDATOR_STACK->top() ); getCell()->notify( Cell::Flags::CellAboutToChange ); - forEach( Instance*, iinstance, getCell()->getSlaveInstances() ) { - iinstance->invalidate( false ); + for ( Instance* instance : getCell()->getSlaveInstances() ) { + instance->invalidate( false ); } } } diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 51f6891c..9ef539dd 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -91,6 +91,8 @@ class Cell : public Entity { , FlattenedNets = 0x00008000 , Placed = 0x00010000 , Routed = 0x00020000 + , MergedQuadTree = 0x00040000 + , Materialized = 0x00080000 }; public: @@ -231,12 +233,13 @@ class Cell : public Entity { private: Library* _library; private: Name _name; + private: Path _shuntedPath; private: InstanceMap _instanceMap; - private: QuadTree _quadTree; + private: QuadTree* _quadTree; private: SlaveInstanceSet _slaveInstanceSet; private: NetMap _netMap; private: PinMap _pinMap; - private: SliceMap _sliceMap; + private: SliceMap* _sliceMap; private: ExtensionSliceMap _extensionSlices; private: MarkerSet _markerSet; private: Box _abutmentBox; @@ -268,11 +271,11 @@ class Cell : public Entity { public: static Slot* getFlagSlot( unsigned int ); public: InstanceMap& _getInstanceMap() {return _instanceMap;}; - public: QuadTree* _getQuadTree() {return &_quadTree;}; + public: QuadTree* _getQuadTree() {return _quadTree;}; public: SlaveInstanceSet& _getSlaveInstanceSet() {return _slaveInstanceSet;}; public: NetMap& _getNetMap() {return _netMap;}; public: PinMap& _getPinMap() {return _pinMap;}; - public: SliceMap& _getSliceMap() {return _sliceMap;}; + public: SliceMap* _getSliceMap() {return _sliceMap;}; public: ExtensionSliceMap& _getExtensionSliceMap() {return _extensionSlices;}; public: MarkerSet& _getMarkerSet() {return _markerSet;}; public: Cell* _getNextOfLibraryCellMap() const {return _nextOfLibraryCellMap;}; @@ -292,8 +295,11 @@ class Cell : public Entity { public: void _removeSlaveEntity(Entity* entity, Entity* slaveEntity); public: void _getSlaveEntities(SlaveEntityMap::iterator& begin, SlaveEntityMap::iterator& end); public: void _getSlaveEntities(Entity* entity, SlaveEntityMap::iterator& begin, SlaveEntityMap::iterator& end); - public: void _insertSlice ( ExtensionSlice* ); - public: void _removeSlice ( ExtensionSlice* ); + public: void _insertSlice(ExtensionSlice*); + public: void _removeSlice(ExtensionSlice*); + public: void _slaveAbutmentBox(Cell*); + public: void _changeQuadTree(Cell*); + public: void _setShuntedPath(Path path) { _shuntedPath=path; } // Constructors // ************ @@ -307,6 +313,8 @@ class Cell : public Entity { public: virtual Box getBoundingBox() const; public: Library* getLibrary() const {return _library;}; public: const Name& getName() const {return _name;}; + public: const Flags& getFlags() const { return _flags; } + public: Path getShuntedPath() const { return _shuntedPath; } public: Instance* getInstance(const Name& name) const {return _instanceMap.getElement(name);}; public: Instances getInstances() const {return _instanceMap.getElements();}; public: Instances getPlacedInstances() const; @@ -339,7 +347,7 @@ class Cell : public Entity { public: Nets getGroundNets() const; public: Pin* getPin(const Name& name) const {return _pinMap.getElement(name);}; public: Pins getPins() const {return _pinMap.getElements();}; - public: Slice* getSlice(const Layer* layer) const {return _sliceMap.getElement(layer);}; + public: Slice* getSlice(const Layer* layer) const {return _sliceMap->getElement(layer);}; public: Slices getSlices(const Layer::Mask& mask = ~0) const; public: const ExtensionSliceMap& getExtensionSliceMap() const { return _extensionSlices; }; public: ExtensionSlice* getExtensionSlice(const Name& name) const; @@ -379,6 +387,9 @@ class Cell : public Entity { public: bool isTerminal() const {return _flags.isset(Flags::Terminal);}; public: bool isFlattenLeaf() const {return _flags.isset(Flags::FlattenLeaf);}; public: bool isLeaf() const; + public: bool isUnique() const; + public: bool isUniquified() const; + public: bool isUniquifyMaster() const; public: bool isPad() const {return _flags.isset(Flags::Pad);}; public: bool isFlattenedNets() const {return _flags.isset(Flags::FlattenedNets);}; public: bool isPlaced() const {return _flags.isset(Flags::Placed);}; @@ -390,6 +401,8 @@ class Cell : public Entity { public: void setName(const Name& name); public: void setAbutmentBox(const Box& abutmentBox); + public: void slaveAbutmentBox(Cell*); + public: void unslaveAbutmentBox(Cell*); public: void setTerminal(bool isTerminal) {_flags.set(Flags::Terminal,isTerminal);}; public: void setFlattenLeaf(bool isFlattenLeaf) {_flags.set(Flags::FlattenLeaf,isFlattenLeaf);}; public: void setPad(bool isPad) {_flags.set(Flags::Pad,isPad);}; @@ -397,6 +410,7 @@ class Cell : public Entity { public: void createRoutingPadRings(unsigned int flags=Flags::BuildRings); public: void setFlags(unsigned int flags) { _flags |= flags; } public: void resetFlags(unsigned int flags) { _flags &= ~flags; } + public: bool updatePlacedFlag(); public: void materialize(); public: void unmaterialize(); public: Cell* getClone(); diff --git a/hurricane/src/hurricane/hurricane/Instance.h b/hurricane/src/hurricane/hurricane/Instance.h index 975e0d8f..538714b7 100644 --- a/hurricane/src/hurricane/hurricane/Instance.h +++ b/hurricane/src/hurricane/hurricane/Instance.h @@ -137,6 +137,9 @@ class Instance : public Go { public: bool isFixed() const {return _placementStatus == PlacementStatus::FIXED;}; public: bool isTerminal() const; public: bool isLeaf() const; + public: bool isUnique() const; + public: bool isUniquified() const; + public: bool isUniquifyMaster() const; // Filters // ******* @@ -162,6 +165,7 @@ class Instance : public Go { public: void setPlacementStatus(const PlacementStatus& placementstatus); public: void setMasterCell(Cell* masterCell, bool secureFlag = true); public: void uniquify(); + public: void slaveAbutmentBox(); public: Instance* getClone(Cell* cloneCell) const; // Others diff --git a/hurricane/src/hurricane/hurricane/Query.h b/hurricane/src/hurricane/hurricane/Query.h index 509b992c..5cac52d8 100644 --- a/hurricane/src/hurricane/hurricane/Query.h +++ b/hurricane/src/hurricane/hurricane/Query.h @@ -210,7 +210,7 @@ namespace Hurricane { instance->getTransformation().getInvert().applyOn ( child->_area ); parent->_transformation.applyOn ( child->_transformation ); - child->_path = Path ( parent->_path, instance ); + child->_path = Path ( Path(parent->_path,instance->getCell()->getShuntedPath()) , instance ); } diff --git a/hurricane/src/isobar/PyCell.cpp b/hurricane/src/isobar/PyCell.cpp index 89710f17..dc846f25 100644 --- a/hurricane/src/isobar/PyCell.cpp +++ b/hurricane/src/isobar/PyCell.cpp @@ -690,8 +690,11 @@ extern "C" { // Standart Predicates (Attributes). - DirectGetBoolAttribute(PyCell_isTerminal, isTerminal ,PyCell,Cell) - DirectGetBoolAttribute(PyCell_isLeaf, isLeaf ,PyCell,Cell) + DirectGetBoolAttribute(PyCell_isTerminal , isTerminal ,PyCell,Cell) + DirectGetBoolAttribute(PyCell_isLeaf , isLeaf ,PyCell,Cell) + DirectGetBoolAttribute(PyCell_isUnique , isUnique ,PyCell,Cell) + DirectGetBoolAttribute(PyCell_isUniquified , isUniquified ,PyCell,Cell) + DirectGetBoolAttribute(PyCell_isUniquifyMaster, isUniquifyMaster ,PyCell,Cell) GetBoundStateAttribute(PyCell_isPyBound ,PyCell,Cell) @@ -727,6 +730,9 @@ extern "C" { , { "getAbutmentBox" , (PyCFunction)PyCell_getAbutmentBox , METH_NOARGS , "Returns the abutment box of the cell(which is defined by the designer unlike the bounding box which is managed dynamically)" } , { "isTerminal" , (PyCFunction)PyCell_isTerminal , METH_NOARGS , "Returns true if the cell is marked as terminal, else false." } , { "isLeaf" , (PyCFunction)PyCell_isLeaf , METH_NOARGS , "Returns true if the cell is a leaf of the hierarchy, else false." } + , { "isUnique" , (PyCFunction)PyCell_isUnique , METH_NOARGS , "Returns true if the cell has one or less instance." } + , { "isUniquified" , (PyCFunction)PyCell_isUniquified , METH_NOARGS , "Returns true if the cell is the result of an uniquification." } + , { "isUniquifyMaster" , (PyCFunction)PyCell_isUniquifyMaster , METH_NOARGS , "Returns true if the cell is the reference for an uniquification." } , { "isBound" , (PyCFunction)PyCell_isPyBound , METH_NOARGS , "Returns true if the cell is bounded to the hurricane cell" } , { "setName" , (PyCFunction)PyCell_setName , METH_VARARGS, "Allows to change the cell name." } , { "setAbutmentBox" , (PyCFunction)PyCell_setAbutmentBox , METH_VARARGS, "Sets the cell abutment box." } diff --git a/hurricane/src/isobar/PyInstance.cpp b/hurricane/src/isobar/PyInstance.cpp index 79957557..7f2fdf67 100644 --- a/hurricane/src/isobar/PyInstance.cpp +++ b/hurricane/src/isobar/PyInstance.cpp @@ -293,6 +293,19 @@ extern "C" { } + static PyObject* PyInstance_slaveAbutmentBox ( PyInstance *self ) + { + trace << "PyInstance_slaveAbutmentBox ()" << endl; + METHOD_HEAD ( "Instance.slaveAbutmentBox()" ) + + HTRY + instance->slaveAbutmentBox(); + HCATCH + + Py_RETURN_NONE; + } + + static PyObject* PyInstance_getClone ( PyInstance *self, PyObject* args ) { @@ -379,6 +392,7 @@ extern "C" { , { "setPlacementStatus" , (PyCFunction)PyInstance_setPlacementStatus , METH_VARARGS, "Allows to modify the instance placement status." } , { "setMasterCell" , (PyCFunction)PyInstance_setMasterCell , METH_VARARGS, "Allows to change the cell referenced by this instance." } , { "uniquify" , (PyCFunction)PyInstance_uniquify , METH_NOARGS , "Uniquify the Instance (clone it's master Cell)." } + , { "slaveAbutmentBox" , (PyCFunction)PyInstance_slaveAbutmentBox , METH_NOARGS , "Bind instance's master Cell and owner Cell together." } , { "getClone" , (PyCFunction)PyInstance_getClone , METH_VARARGS, "Create a clone of this Instance into the cloned Cell (placement only)." } , { "destroy" , (PyCFunction)PyInstance_destroy , METH_NOARGS , "Destroy associated hurricane object The python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */