diff --git a/crlcore/src/ccore/crlcore/LefImport.h b/crlcore/src/ccore/crlcore/LefImport.h index 1a160440..c55d0f6e 100644 --- a/crlcore/src/ccore/crlcore/LefImport.h +++ b/crlcore/src/ccore/crlcore/LefImport.h @@ -29,8 +29,9 @@ namespace CRL { class LefImport { public: - static void reset (); - static Hurricane::Library* load ( std::string fileName ); + static void reset (); + static Hurricane::Library* load ( std::string fileName ); + static void setMergeLibrary ( Hurricane::Library* ); }; diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index 5da960ac..593b1392 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -33,6 +33,7 @@ #include "hurricane/Contact.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" +#include "hurricane/Rectilinear.h" #include "hurricane/Cell.h" #include "hurricane/Library.h" #include "hurricane/UpdateSession.h" @@ -71,6 +72,7 @@ namespace { class LefParser { public: + static void setMergeLibrary ( Library* ); static DbU::Unit fromLefUnits ( int ); static Layer* getLayer ( string ); static void addLayer ( string, Layer* ); @@ -121,6 +123,7 @@ namespace { void _pinStdPostProcess (); void _pinPadPostProcess (); private: + static Library* _mergeLibrary; string _file; string _libraryName; Library* _library; @@ -174,11 +177,16 @@ namespace { inline void LefParser::clearPinSegments () { _pinSegments.clear(); } + Library* LefParser::_mergeLibrary = nullptr; map LefParser::_layerLut; DbU::Unit LefParser::_coreSiteX = 0; DbU::Unit LefParser::_coreSiteY = 0; + void LefParser::setMergeLibrary ( Library* library ) + { _mergeLibrary = library; } + + void LefParser::reset () { _layerLut.clear(); @@ -272,6 +280,11 @@ namespace { Library* LefParser::createLibrary () { + if (_mergeLibrary) { + _library = _mergeLibrary; + return _library; + } + DataBase* db = DataBase::getDB(); Library* rootLibrary = db->getRootLibrary(); if (not rootLibrary) rootLibrary = Library::create( db, "RootLibrary" ); @@ -499,6 +512,17 @@ namespace { } cdebug_log(100,0) << "| " << segment << endl; } + + if (geoms->itemType(igeom) == lefiGeomPolygonE) { + lefiGeomPolygon* polygon = geoms->getPolygon(igeom); + vector points; + for ( int ipoint=0 ; ipointnumPoints ; ++ipoint ) { + points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint]) + , parser->fromUnitsMicrons(polygon->y[ipoint]) )); + } + Rectilinear::create( blockageNet, blockageLayer, points ); + continue; + } } return 0; @@ -647,6 +671,16 @@ namespace { //cerr << " | " << segment << endl; continue; } + if (geoms->itemType(igeom) == lefiGeomPolygonE) { + lefiGeomPolygon* polygon = geoms->getPolygon(igeom); + vector points; + for ( int ipoint=0 ; ipointnumPoints ; ++ipoint ) { + points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint]) + , parser->fromUnitsMicrons(polygon->y[ipoint]) )); + } + Rectilinear::create( net, layer, points ); + continue; + } if (geoms->itemType(igeom) == lefiGeomClassE) { // Ignore CLASS . Deduced from segments positions. continue; @@ -963,4 +997,12 @@ namespace CRL { } + void LefImport::setMergeLibrary ( Library* library ) + { +#if defined(HAVE_LEFDEF) + LefParser::setMergeLibrary( library ); +#endif + } + + } // End of CRL namespace. diff --git a/crlcore/src/pyCRL/PyLefImport.cpp b/crlcore/src/pyCRL/PyLefImport.cpp index 213ab34e..623e361c 100644 --- a/crlcore/src/pyCRL/PyLefImport.cpp +++ b/crlcore/src/pyCRL/PyLefImport.cpp @@ -43,6 +43,8 @@ namespace CRL { using Isobar::ParseTwoArg; using Isobar::__cs; using Isobar::PyLibrary_Link; + using Isobar::PyTypeLibrary; + using Isobar::PyLibrary; extern "C" { @@ -86,14 +88,37 @@ extern "C" { } + static PyObject* PyLefImport_setMergeLibrary ( PyObject*, PyObject* args ) + { + cdebug_log(30,0) << "PyLefImport_setMergeLibrary()" << endl; + HTRY + PyObject* pyLibrary = NULL; + if (PyArg_ParseTuple( args, "O:LefImport.setMergeLibrary", &pyLibrary )) { + if (IsPyLibrary(pyLibrary)) { + LefImport::setMergeLibrary( PYLIBRARY_O(pyLibrary) ); + } else { + PyErr_SetString( ConstructorError, "LefImport.setMergeLibrary(): Bad parameter type (not a Library)." ); + return NULL; + } + } else { + PyErr_SetString( ConstructorError, "LefImport.setMergeLibrary(): Bad number of parameters." ); + return NULL; + } + HCATCH + Py_RETURN_NONE; + } + + // Standart Destroy (Attribute). PyMethodDef PyLefImport_Methods[] = - { { "load" , (PyCFunction)PyLefImport_load , METH_VARARGS|METH_STATIC + { { "load" , (PyCFunction)PyLefImport_load , METH_VARARGS|METH_STATIC , "Load a complete Cadence LEF library." } - , { "reset" , (PyCFunction)PyLefImport_reset , METH_NOARGS|METH_STATIC + , { "reset" , (PyCFunction)PyLefImport_reset , METH_NOARGS|METH_STATIC , "Reset the Cadence LEF parser (clear technology)." } + , { "setMergeLibrary" , (PyCFunction)PyLefImport_setMergeLibrary, METH_VARARGS|METH_STATIC + , "Merge into this library instead of creating a new one." } //, { "destroy" , (PyCFunction)PyLefImport_destroy , METH_VARARGS // , "Destroy the associated hurricane object. The python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ diff --git a/cumulus/src/designflow/technos.py b/cumulus/src/designflow/technos.py index b9d980e2..0aac5c7d 100644 --- a/cumulus/src/designflow/technos.py +++ b/cumulus/src/designflow/technos.py @@ -304,3 +304,52 @@ def setupTSMC_c180_c4m ( checkToolkit=None, ndaTop=None ): Yosys.setLiberty( liberty ) ShellEnv.CHECK_TOOLKIT = Where.checkToolkit.as_posix() + + +def setupGF180MCU_GF ( checkToolkit=None, pdkTop=None ): + from .. import Cfg + from .. import Viewer + from .. import CRL + from ..helpers import setNdaTopDir, overlay, l, u, n + from .yosys import Yosys + + if isinstance(pdkTop,str): + pdkTop = Path( pdkTop ) + if not pdkTop: + print( '[ERROR] technos.setupGF180MCU_GF(): pdkTop directory has *not* been set.' ) + if not pdkTop.is_dir(): + print( '[ERROR] technos.setupSky130_c4m(): pdkTop directory do *not* exists:' ) + print( ' "{}"'.format(pdkTop.as_posix()) ) + + Where( checkToolkit ) + + cellsTop = pdkTop / 'libraries' / 'gf180mcu_fd_sc_mcu9t5v0' / 'latest' / 'cells' + #liberty = pdkTop / 'libraries' / 'gf180mcu_fd_sc_mcu9t5v0' / 'latest' / 'liberty' / 'gf180mcu_fd_sc_mcu9t5v0__tt_025C_5v00.lib' + liberty = pdkTop / 'FULL.lib' + + from coriolis.technos.node180.gf180mcu import techno + from coriolis.technos.node180.gf180mcu import mcu9t5v0 + techno.setup() + mcu9t5v0.setup( cellsTop ) + + with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg: + cfg.misc.catchCore = False + cfg.misc.minTraceLevel = 12300 + cfg.misc.maxTraceLevel = 12400 + cfg.misc.info = False + cfg.misc.paranoid = False + cfg.misc.bug = False + cfg.misc.logMode = True + cfg.misc.verboseLevel1 = False + cfg.misc.verboseLevel2 = False + cfg.etesian.graphics = 2 + cfg.anabatic.topRoutingLayer = 'm4' + cfg.katana.eventsLimit = 4000000 + af = CRL.AllianceFramework.get() + #lg5 = af.getRoutingGauge( 'mcu9t' ).getLayerGauge( 5 ) + #lg5.setType( CRL.RoutingLayerGauge.PowerSupply ) + env = af.getEnvironment() + env.setCLOCK( '^sys_clk$|^ck|^jtag_tck$' ) + + Yosys.setLiberty( liberty ) + ShellEnv.CHECK_TOOLKIT = Where.checkToolkit.as_posix()