From df972b725050021f31708e3c117591c6d81b7800 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 28 Nov 2021 19:03:02 +0100 Subject: [PATCH] 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. --- crlcore/src/ccore/AllianceFramework.cpp | 17 +++++----- crlcore/src/ccore/crlcore/AllianceFramework.h | 31 ++++++++++--------- hurricane/src/hurricane/hurricane/Cell.h | 18 +++++++---- hurricane/src/isobar/PyCell.cpp | 29 +++++++++++++++++ katana/src/KatanaEngine.cpp | 6 ++-- 5 files changed, 71 insertions(+), 30 deletions(-) diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp index 80ca8133..18e16f74 100644 --- a/crlcore/src/ccore/AllianceFramework.cpp +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -859,19 +859,22 @@ namespace CRL { size_t gates = 0; for ( Instance* instance : cell->getInstances() ) { + Cell* masterCell = instance->getMasterCell(); CatalogProperty *catalogProperty = static_cast - (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; diff --git a/crlcore/src/ccore/crlcore/AllianceFramework.h b/crlcore/src/ccore/crlcore/AllianceFramework.h index 47bc4f66..5bf83b9e 100644 --- a/crlcore/src/ccore/crlcore/AllianceFramework.h +++ b/crlcore/src/ccore/crlcore/AllianceFramework.h @@ -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 ); diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index baa07b5d..36706bf7 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -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); diff --git a/hurricane/src/isobar/PyCell.cpp b/hurricane/src/isobar/PyCell.cpp index f93680f9..70c20055 100644 --- a/hurricane/src/isobar/PyCell.cpp +++ b/hurricane/src/isobar/PyCell.cpp @@ -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 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 ." } , { "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"); } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index 07bd3843..c5f3210a 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -201,7 +201,7 @@ namespace Katana { { //Entity::setMemoryLimit( 1024 ); // 1Gb. addMeasure( "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(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++ ) {