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).
This commit is contained in:
Jean-Paul Chaput 2015-06-26 18:35:11 +02:00
parent 61f2b8630f
commit ae6eeb8f56
17 changed files with 347 additions and 209 deletions

View File

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

View File

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

View File

@ -472,11 +472,14 @@ namespace Etesian {
Instance* instance = static_cast<Instance*>(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();

View File

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

View File

@ -39,6 +39,16 @@
* \section secInstancePredefinedFilters Predefined filters
*
* <b>Hurricane::Instance::getIsUnderFilter</b>
*
*
* \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.
*/

View File

@ -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<Instance*> toUniquify;
set<Cell*> 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 ) );

View File

@ -1775,7 +1775,7 @@ Instances Cell::getInstancesUnder(const Box& area) const
// *****************************************************
{
// return _quadTree.getGosUnder(area).getSubSet<Instance*>();
return SubTypeCollection<Go*, Instance*>(_quadTree.getGosUnder(area));
return SubTypeCollection<Go*, Instance*>(_quadTree->getGosUnder(area));
}
Instances Cell::getSlaveInstances() const
@ -1951,21 +1951,21 @@ Rubbers Cell::getRubbers() const
// *****************************
{
// return _quadTree.getGos().getSubSet<Rubber*>();
return SubTypeCollection<Go*, Rubber*>(_quadTree.getGos());
return SubTypeCollection<Go*, Rubber*>(_quadTree->getGos());
}
Rubbers Cell::getRubbersUnder(const Box& area) const
// *************************************************
{
// return (area.isEmpty()) ? Rubbers() : _quadTree.getGosUnder(area).getSubSet<Rubber*>();
return SubTypeCollection<Go*, Rubber*>(_quadTree.getGosUnder(area));
return SubTypeCollection<Go*, Rubber*>(_quadTree->getGosUnder(area));
}
Markers Cell::getMarkersUnder(const Box& area) const
// *************************************************
{
// return (area.isEmpty()) ? Markers() : _quadTree.getGosUnder(area).getSubSet<Marker*>();
return SubTypeCollection<Go*, Marker*>(_quadTree.getGosUnder(area));
return SubTypeCollection<Go*, Marker*>(_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();
}

View File

@ -81,7 +81,6 @@ namespace Hurricane {
{
size_t nbRoutingPads = 0;
HyperNet hyperNet ( _netOccurrence );
RoutingPad* previousRp = NULL;
RoutingPad* currentRp = NULL;
forEach ( Occurrence, ioccurrence, hyperNet.getLeafPlugOccurrences() ) {

View File

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

View File

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

View File

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

View File

@ -90,13 +90,13 @@ void UpdateSession::_destroy()
UPDATOR_STACK->pop();
vector<Cell*> changedCells;
forEach( DBo*, iowner, getOwners() ) {
Cell* cell = dynamic_cast<Cell*>(*iowner);
for ( DBo* owner : getOwners() ) {
Cell* cell = dynamic_cast<Cell*>(owner);
if (cell) {
//cerr << "Notify Cell::CellChanged to: " << cell << endl;
changedCells.push_back( cell );
} else {
Go* go = dynamic_cast<Go*>(*iowner);
Go* go = dynamic_cast<Go*>(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 );
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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