Support for placing *one* block of a Cell in Etesian.

* Change: In Hurricane::Cell_LeafInstanceOccurrences, add the ability to
    walkthrough the leaf of one specific top-level instance.
* Change: In Hurricane::Cell_NonLeafInstanceOccurrences, add the ability to
    walkthrough the leaf of one specific top-level instance.
* Change: In Hurricane::Cell:
    getLeafInstanceOccurrences() and getNonLeafInstanceOccurrences(), now
    have a parameter Instance* to select the leafs we want to walk through.
    If set NULL (default value) browse through all the instances,
    as before.
* Change: In Hurricane::DeepNet, add forgotten Inspector support.
* New: In EtesianEngine, add a "block" (and Instance) attribute to allow
    the placement of one specific bloc. If we want to place the core of
    a chip and take into account the external terminals (if they are not
    already fixed as Pins at the edge of *said* block). We must place
    the core *in the context* of it's instanciation in the corona.
      Note for G. Gouvine : Pin & external RP should be taken into account
    starting at line 629 of EtesianEngine.cpp...
* New: In cumulus/plugins/chip/Chip.py, make use of the new block
    placement feature of ETesian.
* Bug: In KatanaEngine::create(), perform a pre-check to prevent trying to
    route whole chip, which is forbidden an leads to annoying core-dumps.
    Routing must take place "at most" at Corona level.
* Bug: In KatanaEngine::PowerRails, create a plane for METAL1 blockage.
    Not completely sure this was a bug...
This commit is contained in:
Jean-Paul Chaput 2019-08-04 17:33:03 +02:00
parent 1b444d8f49
commit acc3a38f60
10 changed files with 501 additions and 442 deletions

View File

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

View File

@ -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<Instance*>(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<Instance*>(occurrence.getEntity());
Cell* masterCell = instance->getMasterCell();

View File

@ -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<Occurrence> 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<Instance*>(ioccurrence.getEntity());
Instance* instance = static_cast<Instance*>(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<Instance*>(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<Instance*>(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<Instance*>(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>( (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>( (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 );
}

View File

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

View File

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

View File

@ -994,72 +994,46 @@ class Cell_OccurrencesUnder : public Collection<Occurrence> {
};
// ****************************************************************************************************
// Cell_LeafInstanceOccurrences declaration
// ****************************************************************************************************
// -------------------------------------------------------------------
// class : "Cell_LeafInstanceOccurrences".
class Cell_LeafInstanceOccurrences : public Collection<Occurrence> {
// *****************************************************************
// Types
// *****
public: typedef Collection<Occurrence> Inherit;
public: class Locator : public Hurricane::Locator<Occurrence> {
// *********************************************************
public: typedef Hurricane::Locator<Occurrence> 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<Occurrence>* getClone() const;
public: virtual bool isValid() const;
public: virtual void progress();
public: virtual string _getString() const;
public:
typedef Collection<Occurrence> Inherit;
public:
class Locator : public Hurricane::Locator<Occurrence> {
public:
typedef Hurricane::Locator<Occurrence> 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<Occurrence>* 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<Occurrence>* getClone() const;
public: virtual Hurricane::Locator<Occurrence>* 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<Occurrence>* getClone () const;
virtual Hurricane::Locator<Occurrence>* getLocator () const;
virtual string _getString () const;
private:
const Cell* _cell;
const Instance* _topInstance;
};
@ -1136,71 +1110,46 @@ class Cell_LeafInstanceOccurrencesUnder : public Collection<Occurrence> {
};
// ****************************************************************************************************
// Cell_NonLeafInstanceOccurrences declaration
// ****************************************************************************************************
// -------------------------------------------------------------------
// class : "Cell_NonLeafInstanceOccurrences".
class Cell_NonLeafInstanceOccurrences : public Collection<Occurrence> {
// ********************************************************************
// Types
// *****
public: typedef Collection<Occurrence> Inherit;
public: class Locator : public Hurricane::Locator<Occurrence> {
// ************************************************************
public: typedef Hurricane::Locator<Occurrence> 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<Occurrence>* getClone() const;
public: virtual bool isValid() const;
public: virtual void progress();
public: virtual string _getString() const;
public:
typedef Collection<Occurrence> Inherit;
public:
class Locator : public Hurricane::Locator<Occurrence> {
public:
typedef Hurricane::Locator<Occurrence> 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<Occurrence>* 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<Occurrence>* getClone() const;
public: virtual Hurricane::Locator<Occurrence>* 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<Occurrence>* getClone () const;
virtual Hurricane::Locator<Occurrence>* 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<Occurrence>* 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<Occurrence>* 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<Occurrence>* 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<Occurrence>* 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<Occurrence>* 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<Occurrence>* 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<Occurrence>* Cell_NonLeafInstanceOccurrences::getClone() const
// *********************************************************************
{
return new Cell_NonLeafInstanceOccurrences(*this);
}
Locator<Occurrence>* 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<Occurrence>* Cell_NonLeafInstanceOccurrences::getClone () const
{ return new Cell_NonLeafInstanceOccurrences(*this); }
// ****************************************************************************************************
// Cell_NonLeafInstanceOccurrences::Locator implementation
// ****************************************************************************************************
Cell_NonLeafInstanceOccurrences::Locator::Locator(const Cell* cell)
// ****************************************************************
Locator<Occurrence>* 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<Occurrence>* Cell_NonLeafInstanceOccurrences::Locator::getClone() const
// *****************************************************************************
{
return new Locator(*this);
}
bool Cell_NonLeafInstanceOccurrences::Locator::isValid() const
// ************************************************************
{
return ( _state != 0 );
}
Locator<Occurrence>* 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;
}
// ****************************************************************************************************

View File

@ -462,9 +462,9 @@ class Cell : public Entity {
public: Occurrences getOccurrencesUnder(const Box& area, unsigned searchDepth = std::numeric_limits<unsigned int>::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;

View File

@ -82,4 +82,6 @@ namespace Hurricane {
} // Hurricane namespace.
INSPECTOR_P_SUPPORT(Hurricane::DeepNet);
#endif

View File

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

View File

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