From dcfba9ef18eb2998dbae1cfad6e64b14e9ce9b23 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 28 Apr 2021 12:58:47 +0200 Subject: [PATCH] Export Catalog::State creation support to Python. * New: In CRL::PyCatalog, add the second parameter "add" to getState() so we can request the creation of the state if needed. * New: In CRL::PyCatalogState, export setCell() and setInMemory() methods. * Bug: In CRL::Subckt::createModel(), when a cell has a State entry in the catalog, also check that it really has a Cell loaded in memory. If not, throw an exception (and do not crash). --- crlcore/src/ccore/Catalog.cpp | 1 + crlcore/src/ccore/blif/BlifParser.cpp | 6 ++++- crlcore/src/pyCRL/PyCatalog.cpp | 6 +++-- crlcore/src/pyCRL/PyCatalogState.cpp | 33 ++++++++++++++++++++++++++- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/crlcore/src/ccore/Catalog.cpp b/crlcore/src/ccore/Catalog.cpp index b6d8c1a3..ad7df1af 100644 --- a/crlcore/src/ccore/Catalog.cpp +++ b/crlcore/src/ccore/Catalog.cpp @@ -57,6 +57,7 @@ namespace CRL { if (_cell) { if (isPad ()) _cell->setPad ( true ); if (isFeed()) _cell->setFeed( true ); + _library = _cell->getLibrary(); } return _cell; } diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp index d5edc84f..45b5a8f9 100644 --- a/crlcore/src/ccore/blif/BlifParser.cpp +++ b/crlcore/src/ccore/blif/BlifParser.cpp @@ -303,7 +303,11 @@ namespace { if (af->isInCatalog(modelName)) { model = Model::find( modelName ); if (not model) { - model = new Model ( af->getCell( modelName, Catalog::State::Views, 0 ) ); + cell = af->getCell( modelName, Catalog::State::Views, 0 ); + if (not cell) + throw Error( "Subckt::createModel(): Cell \"%s\" has a catalog entry but is not loaded." + , modelName.c_str() ); + model = new Model ( cell ); } } } else { diff --git a/crlcore/src/pyCRL/PyCatalog.cpp b/crlcore/src/pyCRL/PyCatalog.cpp index e511e9c0..7c00b8b2 100644 --- a/crlcore/src/pyCRL/PyCatalog.cpp +++ b/crlcore/src/pyCRL/PyCatalog.cpp @@ -69,13 +69,15 @@ extern "C" { char* name = NULL; Catalog::State* state = NULL; + PyObject* pyAdd = NULL; HTRY METHOD_HEAD("Catalog.getState()") - if ( not PyArg_ParseTuple(args,"s",&name) ) { + if ( not PyArg_ParseTuple(args,"s|O:Catalog.getState",&name,&pyAdd) ) { PyErr_SetString( ConstructorError, "Catalog.getState(): Invalid number or bad type of parameters."); return NULL; } - state = catalog->getState( Name(name) ); + bool add = (pyAdd) and PyObject_IsTrue(pyAdd); + state = catalog->getState( Name(name), add ); HCATCH if (not state) Py_RETURN_FALSE; return PyCatalogState_Link(state); diff --git a/crlcore/src/pyCRL/PyCatalogState.cpp b/crlcore/src/pyCRL/PyCatalogState.cpp index 4565bb4c..be338d55 100644 --- a/crlcore/src/pyCRL/PyCatalogState.cpp +++ b/crlcore/src/pyCRL/PyCatalogState.cpp @@ -43,12 +43,13 @@ namespace CRL { using Isobar::PyLibrary_Link; using Isobar::PyCell; using Isobar::PyCell_Link; + using Isobar::PyTypeCell; extern "C" { -#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(CatalogState,state,function) +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Catalog::State,state,function) // x=================================================================x @@ -65,6 +66,7 @@ extern "C" { DirectGetBoolAttribute(PyCatalogState_isDelete ,isDelete ,PyCatalogState,Catalog::State) DirectGetBoolAttribute(PyCatalogState_isPhysical ,isPhysical ,PyCatalogState,Catalog::State) DirectGetBoolAttribute(PyCatalogState_isLogical ,isLogical ,PyCatalogState,Catalog::State) + DirectGetBoolAttribute(PyCatalogState_isInMemory ,isInMemory ,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setTerminalNetlist,setTerminalNetlist,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setFeed ,setFeed ,PyCatalogState,Catalog::State) @@ -72,6 +74,29 @@ extern "C" { DirectSetBoolAttribute(PyCatalogState_setDelete ,setDelete ,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setPhysical ,setPhysical ,PyCatalogState,Catalog::State) DirectSetBoolAttribute(PyCatalogState_setLogical ,setLogical ,PyCatalogState,Catalog::State) + DirectSetBoolAttribute(PyCatalogState_setInMemory ,setInMemory ,PyCatalogState,Catalog::State) + + + static PyObject* PyCatalogState_setCell ( PyCatalogState* self, PyObject* args ) + { + cdebug_log(20,0) << "PyCatalogState.setCell()" << endl; + METHOD_HEAD("PyCatalogState.setCell()") + HTRY + PyObject* pyCell = NULL; + + if (PyArg_ParseTuple(args,"O:State.setCell()",&pyCell) ) { + if (not IsPyCell(pyCell)) { + PyErr_SetString ( ConstructorError, "State.setCell(): Argument is not of type Cell." ); + return NULL; + } + state->setCell( PYCELL_O(pyCell) ); + } else { + PyErr_SetString ( ConstructorError, "Bad parameters given to State.setCell()." ); + return NULL; + } + HCATCH + Py_RETURN_NONE; + } // Standart Destroy (Attribute). @@ -91,6 +116,10 @@ extern "C" { , "Return true if the Cell possesses a physical (layout) view." } , { "isLogical" , (PyCFunction)PyCatalogState_isLogical, METH_NOARGS , "Return true if the Cell possesses a logical (netlist) view." } + , { "isInMemory" , (PyCFunction)PyCatalogState_isInMemory, METH_NOARGS + , "Return true if the Cell is already loaded in memory." } + , { "setCell" , (PyCFunction)PyCatalogState_setCell, METH_VARARGS + , "Set the cell associated with this state." } , { "setTerminalNetlist", (PyCFunction)PyCatalogState_setTerminalNetlist, METH_VARARGS , "Sets/reset the TerminalNetlist flag of a Cell." } , { "setFeed" , (PyCFunction)PyCatalogState_setFeed, METH_VARARGS @@ -103,6 +132,8 @@ extern "C" { , "Sets/reset the Pysical flag of a Cell." } , { "setLogical" , (PyCFunction)PyCatalogState_setLogical, METH_VARARGS , "Sets/reset the Logical flag of a Cell." } + , { "setInMemory" , (PyCFunction)PyCatalogState_setInMemory, METH_VARARGS + , "Sets/reset the in memory flag of a Cell." } , {NULL, NULL, 0, NULL} /* sentinel */ };