Allow Hurricane::Query to stop on master cells with designated flags.

* New: In Query & QueryStack, add a new stop criterion "stopCellFlags"
    based on the flags of the instances master cell. The instance will
    still be processed, but not it's childs. Typically used to stop
    exploring on "AbstractedSupply" cells.
      Exported in the Python interface.
* New: In Cell::Flags, new value "AbstractedSupply" to mark Cells from
    which an abstract has been built for supplies & blockages. But *not*
    for common nets. Helps reduce the recursion through the hierarchy
    when building supply line in FlattenPower.
      Export setter/getter in the Python interface.
* New: In Instance, add a "PruneMaster" filter to stop hierarchical
    exploration on instances which master cells have at least one of
    the given flags set.
* Change: In NetExternalcomponents::isInternal(), use "const Component*"
    instead of "Component*".
* Bug: In Cell::Flags, the NoFlags must be *zero*, not *one*! And we
    can reclaim that bit for future use.
* Cleanup: In Hurricane::Cell, remove changeQuadTree() related methods.
    Fusing various Cell's QuadTree is not a viable idea.
* Cleanup: In Hurricane::Instance, remove no longer used "_flags"
    attributes.
This commit is contained in:
Jean-Paul Chaput 2021-03-02 12:17:13 +01:00
parent d00a51029e
commit a6492f6edc
10 changed files with 106 additions and 92 deletions

View File

@ -1190,32 +1190,6 @@ void Cell::_slaveAbutmentBox ( Cell* topCell )
}
put( slaveds );
_flags.set( Flags::SlavedAb );
//_changeQuadTree( 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();
}
@ -1256,10 +1230,8 @@ void Cell::_preDestroy()
for ( Slice* slice : getSlices() ) slice->_destroy();
while ( not _extensionSlices.empty() ) _removeSlice( _extensionSlices.begin()->second );
if (not _flags.isset(Flags::MergedQuadTree)) {
delete _sliceMap;
delete _quadTree;
}
delete _sliceMap;
delete _quadTree;
_library->_getCellMap()._remove( this );
@ -1420,13 +1392,14 @@ void Cell::_toJsonCollections(JsonWriter* writer) const
if (not _flags) return "<NoFlags>";
string s = "<";
if (_flags & Pad ) { s += "Pad"; }
if (_flags & TerminalNetlist) { if (s.size() > 1) s += "|"; s += "TerminalNetlist"; }
if (_flags & FlattenedNets ) { if (s.size() > 1) s += "|"; s += "FlattenedNets"; }
if (_flags & Placed ) { if (s.size() > 1) s += "|"; s += "Placed"; }
if (_flags & Routed ) { if (s.size() > 1) s += "|"; s += "Routed"; }
if (_flags & SlavedAb ) { if (s.size() > 1) s += "|"; s += "SlavedAb"; }
if (_flags & Materialized ) { if (s.size() > 1) s += "|"; s += "Materialized"; }
if (_flags & Pad ) { s += "Pad"; }
if (_flags & TerminalNetlist ) { if (s.size() > 1) s += "|"; s += "TerminalNetlist"; }
if (_flags & FlattenedNets ) { if (s.size() > 1) s += "|"; s += "FlattenedNets"; }
if (_flags & Placed ) { if (s.size() > 1) s += "|"; s += "Placed"; }
if (_flags & Routed ) { if (s.size() > 1) s += "|"; s += "Routed"; }
if (_flags & AbstractedSupply) { if (s.size() > 1) s += "|"; s += "AbstractedSupply"; }
if (_flags & SlavedAb ) { if (s.size() > 1) s += "|"; s += "SlavedAb"; }
if (_flags & Materialized ) { if (s.size() > 1) s += "|"; s += "Materialized"; }
s += ">";
return s;

View File

@ -109,9 +109,6 @@ class Instance_IsTerminalNetlistFilter : public Filter<Instance*>
{ return instance->isTerminalNetlist(); };
virtual string _getString () const
{ return "<" + _TName("Instance::IsTerminalNetlistFilter") + ">"; };
private:
uint32_t _flags;
};
class Instance_IsUnplacedFilter : public Filter<Instance*> {
@ -165,6 +162,24 @@ class Instance_IsFixedFilter : public Filter<Instance*> {
};
class Instance_PruneMasterFilter : public Filter<Instance*>
{
public:
Instance_PruneMasterFilter ( Cell::Flags flags ) : _flags(flags) {};
Instance_PruneMasterFilter ( const Instance_PruneMasterFilter& filter ) : _flags(filter._flags) {};
Instance_PruneMasterFilter& operator= ( const Instance_PruneMasterFilter& filter )
{ _flags = filter._flags; return *this; };
virtual Filter<Instance*>* getClone () const
{ return new Instance_PruneMasterFilter( *this ); };
virtual bool accept ( Instance* instance ) const
{ return instance->getMasterCell()->getFlags().isset(_flags); };
virtual string _getString () const
{ return "<" + _TName("Instance::PruneMasterFilter") + getString(_flags) + ">"; };
private:
Cell::Flags _flags;
};
// ****************************************************************************************************
// Instance implementation
// ****************************************************************************************************
@ -345,6 +360,13 @@ InstanceFilter Instance::getIsNotUnplacedFilter()
return !Instance_IsUnplacedFilter();
}
InstanceFilter Instance::getPruneMasterFilter( uint64_t flags )
// ************************************************************
{
return Instance_PruneMasterFilter( flags );
}
void Instance::materialize()
// *************************
{

View File

@ -84,10 +84,10 @@ namespace Hurricane {
}
bool NetExternalComponents::isExternal ( Component* component )
bool NetExternalComponents::isExternal ( const Component* component )
{
Net* net = component->getNet();
if (!net->isExternal()) return false;
if (not net->isExternal()) return false;
return component->getProperty(_name) != NULL;
}

View File

@ -51,6 +51,7 @@ namespace Hurricane {
, _topTransformation ()
, _startLevel (0)
, _stopLevel (std::numeric_limits<unsigned int>::max())
, _stopCellFlags (Cell::Flags::NoFlags)
, _instanceCount (0)
{ }

View File

@ -72,7 +72,7 @@ class Cell : public Entity {
public: class Flags : public BaseFlags {
public:
enum Flag { NoFlags = (1 << 0)
enum Flag { NoFlags = 0
, BuildRings = (1 << 1)
, BuildClockRings = (1 << 2)
, BuildSupplyRings = (1 << 3)
@ -89,9 +89,9 @@ class Cell : public Entity {
, Pad = (1 << 21)
, Feed = (1 << 22)
, FlattenedNets = (1 << 23)
, Placed = (1 << 24)
, Routed = (1 << 25)
, MergedQuadTree = (1 << 26)
, AbstractedSupply = (1 << 24)
, Placed = (1 << 25)
, Routed = (1 << 26)
, SlavedAb = (1 << 27)
, Materialized = (1 << 28)
};
@ -387,7 +387,6 @@ class Cell : public Entity {
public: void _insertSlice(ExtensionSlice*);
public: void _removeSlice(ExtensionSlice*);
public: void _slaveAbutmentBox(Cell*);
public: void _changeQuadTree(Cell*);
public: void _setShuntedPath(Path path) { _shuntedPath=path; }
protected: void _setAbutmentBox(const Box& abutmentBox);
@ -489,6 +488,7 @@ class Cell : public Entity {
public: bool isPad() const {return _flags.isset(Flags::Pad);};
public: bool isFeed() const {return _flags.isset(Flags::Feed);};
public: bool isFlattenedNets() const {return _flags.isset(Flags::FlattenedNets);};
public: bool isAbstractedSupply() const {return _flags.isset(Flags::AbstractedSupply);};
public: bool isPlaced() const {return _flags.isset(Flags::Placed);};
public: bool isRouted() const {return _flags.isset(Flags::Routed);};
public: bool isNetAlias(const Name& name) const;
@ -500,10 +500,11 @@ class Cell : public Entity {
public: void setAbutmentBox(const Box& abutmentBox);
public: void slaveAbutmentBox(Cell*);
public: void unslaveAbutmentBox(Cell*);
public: void setTerminalNetlist(bool isTerminalNetlist) { _flags.set(Flags::TerminalNetlist,isTerminalNetlist); };
public: void setPad(bool isPad) {_flags.set(Flags::Pad,isPad);};
public: void setFeed(bool isFeed) {_flags.set(Flags::Feed,isFeed);};
public: void setRouted(bool isRouted) {_flags.set(Flags::Routed,isRouted);};
public: void setTerminalNetlist(bool state) { _flags.set(Flags::TerminalNetlist,state); };
public: void setPad(bool state) {_flags.set(Flags::Pad,state);};
public: void setFeed(bool state) {_flags.set(Flags::Feed,state);};
public: void setRouted(bool state) {_flags.set(Flags::Routed,state);};
public: void setAbstractedSupply(bool state) { _flags.set(Flags::AbstractedSupply,state); };
public: void flattenNets(uint64_t flags=Flags::BuildRings);
public: void flattenNets(const Instance* instance, uint64_t flags=Flags::BuildRings);
public: void createRoutingPadRings(uint64_t flags=Flags::BuildRings);

View File

@ -17,9 +17,7 @@
// not, see <http://www.gnu.org/licenses/>.
// ****************************************************************************************************
#ifndef HURRICANE_INSTANCE_H
#define HURRICANE_INSTANCE_H
#pragma once
#include "hurricane/Go.h"
#include "hurricane/Plug.h"
#include "hurricane/SharedPath.h"
@ -152,6 +150,7 @@ class Instance : public Go {
public: static InstanceFilter getIsPlacedFilter();
public: static InstanceFilter getIsFixedFilter();
public: static InstanceFilter getIsNotUnplacedFilter();
public: static InstanceFilter getPruneMasterFilter( uint64_t );
// Updators
// ********
@ -264,8 +263,6 @@ inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane:
w->write( getString(status.getCode()) );
}
#endif // HURRICANE_INSTANCE
// ****************************************************************************************************
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved

View File

@ -44,7 +44,7 @@ namespace Hurricane {
static Components get ( const Net* );
static void setInternal ( Component* );
static void setExternal ( Component* );
static bool isExternal ( Component* );
static bool isExternal ( const Component* );
static void toJson ( JsonWriter*, const Net* );
protected:
static StandardRelation* getRelation ( const Net* );

View File

@ -114,6 +114,7 @@ namespace Hurricane {
inline const Transformation& getTopTransformation () const;
inline unsigned int getStartLevel () const;
inline unsigned int getStopLevel () const;
inline Cell::Flags getStopCellFlags () const;
inline Cell* getMasterCell ();
inline Instance* getInstance ();
inline const Box& getArea () const;
@ -128,6 +129,7 @@ namespace Hurricane {
inline void setThreshold ( DbU::Unit threshold );
inline void setStartLevel ( unsigned int level );
inline void setStopLevel ( unsigned int level );
inline void setStopCellFlags ( Cell::Flags );
inline void init ();
inline void updateTransformation ();
inline bool levelDown ();
@ -146,6 +148,7 @@ namespace Hurricane {
Transformation _topTransformation;
unsigned int _startLevel;
unsigned int _stopLevel;
Cell::Flags _stopCellFlags;
size_t _instanceCount;
private:
@ -164,6 +167,7 @@ namespace Hurricane {
inline DbU::Unit QueryStack::getThreshold () const { return _threshold; }
inline unsigned int QueryStack::getStartLevel () const { return _startLevel; }
inline unsigned int QueryStack::getStopLevel () const { return _stopLevel; }
inline Cell::Flags QueryStack::getStopCellFlags () const { return _stopCellFlags; }
inline const Box& QueryStack::getArea () const { return back()->_area; }
inline const Transformation& QueryStack::getTransformation () const { return back()->_transformation; }
inline const Path& QueryStack::getPath () const { return back()->_path; }
@ -192,6 +196,7 @@ namespace Hurricane {
inline void QueryStack::setThreshold ( DbU::Unit threshold ) { _threshold = threshold; }
inline void QueryStack::setStartLevel ( unsigned int level ) { _startLevel = level; }
inline void QueryStack::setStopLevel ( unsigned int level ) { _stopLevel = level; }
inline void QueryStack::setStopCellFlags ( Cell::Flags flags ) { _stopCellFlags = flags; }
inline void QueryStack::init ()
@ -222,12 +227,14 @@ namespace Hurricane {
//child->_path = Path ( Path(parent->_path,instance->getCell()->getShuntedPath()) , instance );
child->_path = Path ( parent->_path, instance );
//cerr << "QueryStack::updateTransformation() " << child->_path << endl;
}
inline bool QueryStack::levelDown ()
{
if ( size() > _stopLevel ) return false;
if (size() > _stopLevel) return false;
if (getMasterCell()->getFlags().isset(_stopCellFlags)) return false;
//cerr << "QueryStack::levelDown(): t:" << DbU::getValueString(getThreshold()) << endl;
Locator<Instance*>* locator =
@ -326,6 +333,7 @@ namespace Hurricane {
// Accessors.
inline unsigned int getStartLevel () const;
inline unsigned int getStopLevel () const;
inline Cell::Flags getStopCellFlags () const;
inline size_t getDepth () const;
inline const Transformation& getTransformation () const;
inline const Box& getArea () const;
@ -363,6 +371,7 @@ namespace Hurricane {
inline void setFilter ( Mask mode );
inline void setStartLevel ( unsigned int level );
inline void setStopLevel ( unsigned int level );
inline void setStopCellFlags ( Cell::Flags );
virtual void doQuery ();
protected:
@ -384,9 +393,11 @@ namespace Hurricane {
inline void Query::setExtensionMask ( ExtensionSlice::Mask mask ) { _extensionMask = mask; }
inline void Query::setStartLevel ( unsigned int level ) { _stack.setStartLevel(level); }
inline void Query::setStopLevel ( unsigned int level ) { _stack.setStopLevel(level); }
inline void Query::setStopCellFlags ( Cell::Flags flags ) { _stack.setStopCellFlags(flags); }
inline unsigned int Query::getStartLevel () const { return _stack.getStartLevel(); }
inline unsigned int Query::getStopLevel () const { return _stack.getStopLevel(); }
inline Cell::Flags Query::getStopCellFlags () const { return _stack.getStopCellFlags(); }
inline size_t Query::getDepth () const { return _stack.size(); }
inline const Box& Query::getArea () const { return _stack.getArea(); }
inline const Transformation& Query::getTransformation () const { return _stack.getTransformation(); }

View File

@ -656,7 +656,7 @@ extern "C" {
// ---------------------------------------------------------------
// Attribute Method : "PyCell_setTerminal ()"
// Attribute Method : "PyCell_setTerminalNetlist ()"
static PyObject* PyCell_setTerminalNetlist ( PyCell *self, PyObject* args ) {
cdebug_log(20,0) << "PyCell_setTerminalNetlist ()" << endl;
@ -673,6 +673,24 @@ extern "C" {
}
// ---------------------------------------------------------------
// Attribute Method : "PyCell_setAbstractedSupply ()"
static PyObject* PyCell_setAbstractedSupply ( PyCell *self, PyObject* args ) {
cdebug_log(20,0) << "PyCell_setAbstractedSupply ()" << endl;
HTRY
METHOD_HEAD( "Cell.setAbstractedSupply()" )
PyObject* arg0 = NULL;
if (not PyArg_ParseTuple(args,"O:Cell.setAbstractedSupply", &arg0)
and PyBool_Check(arg0)) {
return NULL;
}
PyObject_IsTrue(arg0) ? cell->setAbstractedSupply(true) : cell->setAbstractedSupply(false);
HCATCH
Py_RETURN_NONE;
}
// ---------------------------------------------------------------
// Attribute Method : "PyCell_uniquify ()"
@ -808,6 +826,7 @@ extern "C" {
, { "setName" , (PyCFunction)PyCell_setName , METH_VARARGS, "Allows to change the cell name." }
, { "setAbutmentBox" , (PyCFunction)PyCell_setAbutmentBox , METH_VARARGS, "Sets the cell abutment box." }
, { "setTerminalNetlist" , (PyCFunction)PyCell_setTerminalNetlist , METH_VARARGS, "Sets the cell terminal netlist status." }
, { "setAbstractedSupply" , (PyCFunction)PyCell_setAbstractedSupply , METH_VARARGS, "Sets the cell abstracted supply status." }
, { "setRouted" , (PyCFunction)PyCell_setRouted , METH_VARARGS, "Sets the cell routed status." }
, { "uniquify" , (PyCFunction)PyCell_uniquify , METH_VARARGS, "Uniquify the Cell and it's instances up to <depth>." }
, { "getClone" , (PyCFunction)PyCell_getClone , METH_NOARGS , "Return a copy of the Cell (placement only)." }
@ -847,6 +866,7 @@ extern "C" {
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::BuildClockRings ,"Flags_BuildClockRings");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::BuildSupplyRings,"Flags_BuildSupplyRings");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::NoClockFlatten ,"Flags_NoClockFlatten");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::AbstractedSupply,"Flags_AbstractedSupply");
}

View File

@ -125,16 +125,16 @@ extern "C" {
#if defined(__PYTHON_MODULE__)
// +-------------------------------------------------------------+
// | "PyQuery" Attribute Methods |
// +-------------------------------------------------------------+
DirectSetLongAttribute(PyQuery_setThreshold ,setThreshold ,PyQuery,Query)
DirectSetLongAttribute(PyQuery_setStartLevel ,setStartLevel ,PyQuery,Query)
DirectSetLongAttribute(PyQuery_setStopLevel ,setStopLevel ,PyQuery,Query)
DirectSetLongAttribute(PyQuery_setStopCellFlags,setStopCellFlags,PyQuery,Query)
static PyObject* PyQuery_getMasterCell ( PyQuery *self ) {
static PyObject* PyQuery_getMasterCell ( PyQuery *self )
{
cdebug_log(20,0) << "PyQuery.getMasterCell()" << endl;
Cell* cell = NULL;
HTRY
METHOD_HEAD("PyQuery.getMasterCell()")
cell = query->getMasterCell();
@ -144,11 +144,10 @@ extern "C" {
}
static PyObject* PyQuery_getInstance ( PyQuery *self ) {
static PyObject* PyQuery_getInstance ( PyQuery *self )
{
cdebug_log(20,0) << "PyQuery.getInstance()" << endl;
Instance* instance = NULL;
HTRY
METHOD_HEAD("PyQuery.getInstance()")
instance = query->getInstance();
@ -161,14 +160,11 @@ extern "C" {
static PyObject* PyQuery_getPath ( PyQuery *self )
{
cdebug_log(20,0) << "PyQuery_getPath ()" << endl;
METHOD_HEAD( "PyQuery.getPath()" )
PyPath* pyPath = PyObject_NEW( PyPath, &PyTypePath );
if (pyPath == NULL) return NULL;
HTRY
pyPath->_object = new Path ( query->getPath() );
pyPath->_object = new Path ( query->getPath() );
HCATCH
return (PyObject*)pyPath;
@ -178,14 +174,11 @@ extern "C" {
static PyObject* PyQuery_getTransformation ( PyQuery *self )
{
cdebug_log(20,0) << "PyQuery_getTransformation ()" << endl;
METHOD_HEAD( "PyQuery.getTransformation()" )
PyTransformation* pyTransformation = PyObject_NEW( PyTransformation, &PyTypeTransformation );
if (pyTransformation == NULL) return NULL;
HTRY
pyTransformation->_object = new Transformation ( query->getTransformation() );
pyTransformation->_object = new Transformation ( query->getTransformation() );
HCATCH
return (PyObject*)pyTransformation;
@ -196,7 +189,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setCell()" << endl;
METHOD_HEAD("PyQuery.setCell()")
HTRY
PyObject* pyCell = NULL;
@ -219,7 +211,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setFilter()" << endl;
METHOD_HEAD("PyQuery.setFilter()")
HTRY
int mask = 0;
if (PyArg_ParseTuple(args,"i:Query.setFilter()",&mask) ) {
@ -237,7 +228,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setArea()" << endl;
METHOD_HEAD("PyQuery.setArea()")
HTRY
PyObject* pyBox = NULL;
@ -260,7 +250,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setTransformation()" << endl;
METHOD_HEAD("PyQuery.setTransformation()")
HTRY
PyObject* pyTransformation = NULL;
@ -283,7 +272,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setBasicLayer()" << endl;
METHOD_HEAD("PyQuery.setBasicLayer()")
HTRY
PyObject* pyBasicLayer = NULL;
@ -306,7 +294,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setMasterCellCallback()" << endl;
METHOD_HEAD("PyQuery.setMasterCellCallback()")
HTRY
PyObject* pyCallback = NULL;
@ -329,7 +316,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setGoCallback()" << endl;
METHOD_HEAD("PyQuery.setGoCallback()")
HTRY
PyObject* pyCallback = NULL;
@ -352,7 +338,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setMarkerCallback()" << endl;
METHOD_HEAD("PyQuery.setMarkerCallback()")
HTRY
PyObject* pyCallback = NULL;
@ -375,7 +360,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setRubberCallback()" << endl;
METHOD_HEAD("PyQuery.setRubberCallback()")
HTRY
PyObject* pyCallback = NULL;
@ -398,7 +382,6 @@ extern "C" {
{
cdebug_log(20,0) << "PyQuery.setExtensionGoCallback()" << endl;
METHOD_HEAD("PyQuery.setExtensionGoCallback()")
HTRY
PyObject* pyCallback = NULL;
@ -420,15 +403,13 @@ extern "C" {
PyObject* PyQuery_NEW ( PyObject* module, PyObject* args )
{
cdebug_log(20,0) << "PyQuery.new()" << endl;
BaseQuery* query = NULL;
PyQuery* pyQuery = NULL;
HTRY
pyQuery = PyObject_NEW( PyQuery, &PyTypeQuery );
if (pyQuery == NULL) return NULL;
query = new BaseQuery( pyQuery );
pyQuery->_object = query;
pyQuery = PyObject_NEW( PyQuery, &PyTypeQuery );
if (pyQuery == NULL) return NULL;
query = new BaseQuery( pyQuery );
pyQuery->_object = query;
HCATCH
return (PyObject*)pyQuery;
@ -466,6 +447,14 @@ extern "C" {
, "Set the initial transformation applied to the query area." }
, { "setBasicLayer" , (PyCFunction)PyQuery_setBasicLayer , METH_VARARGS
, "Set the BasicLayer on which perform the query." }
, { "setThreshold" , (PyCFunction)PyQuery_setThreshold , METH_VARARGS
, "Quadtree leafs below this size will be pruned." }
, { "setStartLevel" , (PyCFunction)PyQuery_setStartLevel , METH_VARARGS
, "Hierarchical depth from which to start the query." }
, { "setStopLevel" , (PyCFunction)PyQuery_setStopLevel , METH_VARARGS
, "Hierarchical depth below this one will be pruned." }
, { "setStopCellFlags" , (PyCFunction)PyQuery_setStopCellFlags , METH_VARARGS
, "Instances below such flagged master cells wiil be pruned." }
, { "setGoCallback" , (PyCFunction)PyQuery_setGoCallback , METH_VARARGS
, "Set the callback function for the Gos." }
, { "setMarkerCallback" , (PyCFunction)PyQuery_setMarkerCallback , METH_VARARGS