Add Diode/Feed flags in Cell. Correct computation of Instance count.

WARNING: We are partially duplicating the informations pertaining
         to the Alliance catalog (stored in the Catalog property)
	 directly into the Cell. This is needed for Flexlib which
	 is not using the Alliance loading mechanim. Ideally the
	 Catalog information should be moved into the Cell.

* New: In Cell, add new state flags Diode, PowerFeed (in addition to
    Pad & Feed).
      Export flags setter/getter to Python. For Flexlib usage.
* Change: In AllianceFramework::getInstancesCount(), correctly skip
    Diode & Feeds based on Cell flags. Those flags must correctly
    be set in the various Flexlib_fix.py scripts.
This commit is contained in:
Jean-Paul Chaput 2021-11-28 19:03:02 +01:00
parent 01224e6a06
commit df972b7250
5 changed files with 71 additions and 30 deletions

View File

@ -859,19 +859,22 @@ namespace CRL {
size_t gates = 0;
for ( Instance* instance : cell->getInstances() ) {
Cell* masterCell = instance->getMasterCell();
CatalogProperty *catalogProperty = static_cast<CatalogProperty*>
(instance->getMasterCell()->getProperty ( CatalogProperty::getPropertyName()) );
(masterCell->getProperty ( CatalogProperty::getPropertyName()) );
if (catalogProperty) {
Catalog::State* state = catalogProperty->getState();
if ((flags & IgnoreFeeds) and state->isFeed()) continue;
}
if (not (flags & TerminalNetlist) or instance->getMasterCell()->isTerminalNetlist())
++gates;
if (flags & Recursive) {
gates += getInstancesCount( instance->getMasterCell(), flags );
}
if ((flags & IgnoreFeeds ) and masterCell->isFeed ()) continue;
if ((flags & IgnoreDiodes ) and masterCell->isDiode ()) continue;
if ((flags & IgnorePowerFeeds) and masterCell->isPowerFeed()) continue;
++gates;
if ((flags & TerminalNetlist) and masterCell->isTerminalNetlist())
continue;
if (flags & Recursive)
gates += getInstancesCount( masterCell, flags );
}
return gates;

View File

@ -42,20 +42,23 @@ namespace CRL {
class AllianceFramework : public DBo {
typedef DBo Super;
public:
enum FunctionsFlags { NoFlags = 0
, NoPythonInit = (1<<0)
};
enum InstancesCountFlags { Recursive = (1<<0)
, IgnoreFeeds = (1<<1)
, TerminalNetlist = (1<<1)
};
enum LibraryFlags { CreateLibrary = (1<<0)
, AppendLibrary = (1<<1)
, HasCatalog = (1<<2)
};
enum NotifyFlags { AddedLibrary = (1<<0)
, RemovedLibrary = (1<<1)
, ConfigChanged = (1<<2)
enum FunctionsFlags { NoFlags = 0
, NoPythonInit = (1<<0)
};
enum InstancesCountFlags { Recursive = (1<<0)
, IgnoreFeeds = (1<<1)
, IgnoreDiodes = (1<<2)
, IgnorePowerFeeds = (1<<3)
, IgnoreNonLogic = IgnoreFeeds|IgnoreDiodes|IgnorePowerFeeds
, TerminalNetlist = (1<<4)
};
enum LibraryFlags { CreateLibrary = (1<<0)
, AppendLibrary = (1<<1)
, HasCatalog = (1<<2)
};
enum NotifyFlags { AddedLibrary = (1<<0)
, RemovedLibrary = (1<<1)
, ConfigChanged = (1<<2)
};
public:
static AllianceFramework* create ( unsigned long flags=NoFlags );

View File

@ -88,12 +88,14 @@ class Cell : public Entity {
, TerminalNetlist = (1 << 20)
, Pad = (1 << 21)
, Feed = (1 << 22)
, FlattenedNets = (1 << 23)
, AbstractedSupply = (1 << 24)
, Placed = (1 << 25)
, Routed = (1 << 26)
, SlavedAb = (1 << 27)
, Materialized = (1 << 28)
, Diode = (1 << 23)
, PowerFeed = (1 << 24)
, FlattenedNets = (1 << 25)
, AbstractedSupply = (1 << 26)
, Placed = (1 << 27)
, Routed = (1 << 28)
, SlavedAb = (1 << 29)
, Materialized = (1 << 30)
};
public:
@ -487,6 +489,8 @@ class Cell : public Entity {
public: bool isUniquifyMaster() const;
public: bool isPad() const {return _flags.isset(Flags::Pad);};
public: bool isFeed() const {return _flags.isset(Flags::Feed);};
public: bool isDiode() const {return _flags.isset(Flags::Diode);};
public: bool isPowerFeed() const {return _flags.isset(Flags::PowerFeed);};
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);};
@ -503,6 +507,8 @@ class Cell : public Entity {
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 setDiode(bool state) {_flags.set(Flags::Diode,state);};
public: void setPowerFeed(bool state) {_flags.set(Flags::PowerFeed,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);

View File

@ -804,7 +804,18 @@ extern "C" {
DirectGetBoolAttribute(PyCell_isUniquified , isUniquified ,PyCell,Cell)
DirectGetBoolAttribute(PyCell_isUniquifyMaster , isUniquifyMaster ,PyCell,Cell)
DirectGetBoolAttribute(PyCell_isRouted , isRouted ,PyCell,Cell)
DirectGetBoolAttribute(PyCell_isPad , isPad ,PyCell,Cell)
DirectGetBoolAttribute(PyCell_isFeed , isFeed ,PyCell,Cell)
DirectGetBoolAttribute(PyCell_isDiode , isDiode ,PyCell,Cell)
DirectGetBoolAttribute(PyCell_isPowerFeed , isPowerFeed ,PyCell,Cell)
//DirectGetLongAttribute(PyCell_getFlags , getFlags ,PyCell,Cell)
DirectSetBoolAttribute(PyCell_setRouted , setRouted ,PyCell,Cell)
DirectSetBoolAttribute(PyCell_setPad , setPad ,PyCell,Cell)
DirectSetBoolAttribute(PyCell_setFeed , setFeed ,PyCell,Cell)
DirectSetBoolAttribute(PyCell_setDiode , setDiode ,PyCell,Cell)
DirectSetBoolAttribute(PyCell_setPowerFeed , setPowerFeed ,PyCell,Cell)
DirectSetLongAttribute(PyCell_setFlags , setFlags ,PyCell,Cell)
DirectSetLongAttribute(PyCell_resetFlags , resetFlags ,PyCell,Cell)
GetBoundStateAttribute(PyCell_isPyBound ,PyCell,Cell)
@ -814,6 +825,7 @@ extern "C" {
PyMethodDef PyCell_Methods[] =
{ { "create" , (PyCFunction)PyCell_create , METH_VARARGS|METH_STATIC
, "Create a new cell." }
//, { "getFlags" , (PyCFunction)PyCell_getFlags , METH_NOARGS , "Returns state flags." }
, { "getLibrary" , (PyCFunction)PyCell_getLibrary , METH_NOARGS , "Returns the library owning the cell." }
, { "getName" , (PyCFunction)PyCell_getName , METH_NOARGS , "Returns the name of the cell." }
, { "getInstance" , (PyCFunction)PyCell_getInstance , METH_VARARGS, "Returns the instance of name <name> if it exists, else NULL." }
@ -846,12 +858,22 @@ extern "C" {
, { "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." }
, { "isRouted" , (PyCFunction)PyCell_isRouted , METH_NOARGS , "Returns true if the cell is flagged as routed." }
, { "isPad" , (PyCFunction)PyCell_isPad , METH_NOARGS , "Returns true if the cell is flagged as I/O pad." }
, { "isFeed" , (PyCFunction)PyCell_isFeed , METH_NOARGS , "Returns true if the cell is flagged as feed (filler cell)." }
, { "isDiode" , (PyCFunction)PyCell_isDiode , METH_NOARGS , "Returns true if the cell is flagged as diode." }
, { "isPowerFeed" , (PyCFunction)PyCell_isPowerFeed , METH_NOARGS , "Returns true if the cell is flagged as power rail element." }
, { "isBound" , (PyCFunction)PyCell_isPyBound , METH_NOARGS , "Returns true if the cell is bounded to the hurricane cell" }
, { "setFlags" , (PyCFunction)PyCell_setFlags , METH_VARARGS, "Set state flags." }
, { "resetFlags" , (PyCFunction)PyCell_resetFlags , METH_VARARGS, "Reset state flags." }
, { "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." }
, { "setPad" , (PyCFunction)PyCell_setPad , METH_VARARGS, "Sets/reset the cell I/O pad flag." }
, { "setFeed" , (PyCFunction)PyCell_setFeed , METH_VARARGS, "Sets/reset the cell feed (filler cell) flag." }
, { "setDiode" , (PyCFunction)PyCell_setDiode , METH_VARARGS, "Sets/reset the cell diode flag." }
, { "setPowerFeed" , (PyCFunction)PyCell_setPowerFeed , METH_VARARGS, "Sets/reset the cell power rail element flag." }
, { "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)." }
, { "flattenNets" , (PyCFunction)PyCell_flattenNets , METH_VARARGS, "Perform a virtual flatten, possibly limited to one instance." }
@ -891,7 +913,14 @@ extern "C" {
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::BuildSupplyRings,"Flags_BuildSupplyRings");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::NoClockFlatten ,"Flags_NoClockFlatten");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::TerminalNetlist ,"Flags_TerminalNetlist");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::Pad ,"Flags_Pad");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::Feed ,"Flags_Feed");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::Diode ,"Flags_Diode");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::PowerFeed ,"Flags_PowerFeed");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::FlattenedNets ,"Flags_FlattenedNets");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::AbstractedSupply,"Flags_AbstractedSupply");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::Placed ,"Flags_Placed");
LoadObjectConstant(PyTypeCell.tp_dict,Cell::Flags::Routed ,"Flags_Routed");
}

View File

@ -201,7 +201,7 @@ namespace Katana {
{
//Entity::setMemoryLimit( 1024 ); // 1Gb.
addMeasure<size_t>( "Gates"
, AllianceFramework::getInstancesCount(cell,AllianceFramework::IgnoreFeeds
, AllianceFramework::getInstancesCount(cell,AllianceFramework::IgnoreNonLogic
|AllianceFramework::TerminalNetlist
|AllianceFramework::Recursive) );
}
@ -672,8 +672,8 @@ namespace Katana {
ostringstream result;
bool isSymbolic =
const_cast<KatanaEngine*>(this)->getConfiguration()->getRoutingGauge()->isSymbolic();
// Max symbolic wire: 100000L, max real wire: 2mm.
uint64_t maxWL = (isSymbolic) ? 100000 : 2000000;
// Max symbolic wire: 100000L, max real wire: 3mm.
uint64_t maxWL = (isSymbolic) ? 100000 : 3000000;
AutoSegmentLut::const_iterator ilut = _getAutoSegmentLut().begin();
for ( ; ilut != _getAutoSegmentLut().end() ; ilut++ ) {